I have a series of shelves in a warehouse mapped in a database. The shelves themselves contain boxes that are measured by size in cubic feet. I want to perform a query and filter out the locations that have a minimum amount of cubic feet free in their shelves. I am able to run the query that shows the amount of free space, however the WHERE clause to limit the results of the SUM doesn't seem to have any effect.
Here is my query to get all of the shelves with their free space and total space:
Dim shelves As IQueryable(Of Location) = _db.Locations.Include(Function(l) l.Boxes)
.Select(Function(loc) New With
{
.LocationID = loc.LocationID,
.WarehouseID = loc.WarehouseID,
.Warehouse = loc.Warehouse.Name,
.Row = loc.Row,
.Column = loc.Column,
.Bunk = loc.Bunk,
.TotalSpace = loc.Footage,
.FreeSpace = (loc.Footage - loc.Boxes.Select(Function(s) s.Size).DefaultIfEmpty(0).Sum())
}).ToList()
This returns the correct values for each location, including the correct amount of free space. When I introduce the WHERE clause, it has no effect. Here is my query with the WHERE clause included:
Dim shelves As IQueryable(Of Location) = _db.Locations.Include(Function(l) l.Boxes)
.Where(Function(l) (l.Boxes.Select(Function(e) e.Size).DefaultIfEmpty(0).Sum() >= EmptySpace))
.Select(Function(loc) New With
{
.LocationID = loc.LocationID,
.WarehouseID = loc.WarehouseID,
.Warehouse = loc.Warehouse.Name,
.Row = loc.Row,
.Column = loc.Column,
.Bunk = loc.Bunk,
.TotalSpace = loc.Footage,
.FreeSpace = (loc.Footage - loc.Boxes.Select(Function(s) s.Size).DefaultIfEmpty(0).Sum())
}).ToList()
Since .FreeSpace returns the correct values I'm not sure why it can't filter by that same value in my WHERE clause.
Update
You original Where predicate
.Where(Function(l) (l.Boxes.Select(Function(e) e.Size).DefaultIfEmpty(0).Sum() >= EmptySpace))
was not calculating the free space, which is why it had no effect.
You will notice that in your initial select you calculated free space as
(loc.Footage - loc.Boxes.Select(Function(s) s.Size).DefaultIfEmpty(0).Sum())
Notice loc.Footage was missing in the Where predicate.
That would mean that this updated query should work
Dim shelves As IQueryable(Of Location) = _db.Locations.Include(Function(l) l.Boxes)
.Where(Function(loc) (loc.Footage - loc.Boxes.Select(Function(s) s.Size).DefaultIfEmpty(0).Sum()) >= EmptySpace)
.Select(Function(loc) New With
{
.LocationID = loc.LocationID,
.WarehouseID = loc.WarehouseID,
.Warehouse = loc.Warehouse.Name,
.Row = loc.Row,
.Column = loc.Column,
.Bunk = loc.Bunk,
.TotalSpace = loc.Footage,
.FreeSpace = (loc.Footage - loc.Boxes.Select(Function(s) s.Size).DefaultIfEmpty(0).Sum())
}).ToList()
Original Answer
Try applying the filter on the projected objects after the select
Dim shelves As IQueryable(Of Location) = _db.Locations.Include(Function(l) l.Boxes)
.Select(Function(loc) New With
{
.LocationID = loc.LocationID,
.WarehouseID = loc.WarehouseID,
.Warehouse = loc.Warehouse.Name,
.Row = loc.Row,
.Column = loc.Column,
.Bunk = loc.Bunk,
.TotalSpace = loc.Footage,
.FreeSpace = (loc.Footage - loc.Boxes.Select(Function(s) s.Size).DefaultIfEmpty(0).Sum())
})
.Where(Function(loc) loc.FreeSpace >= EmptySpace)
.ToList()
That way the free space is already calculated and included in the anonymous object.
Related
The supposed value for this would is 15.2 sq cm. however, when annotation is moved, it becomes 0.04 sq cm.
I got this data from my application where area is computed as 9658.6572265625 and its calibration value is 0.00157889 which results in 15.2 value.
when the corresponding coordinates in pdf space are provided (see code below), the area computed is 5433.001953125.
so i compute the calibration value in pdf space like this.
ratio = area / pdfArea
pdfCalibrationValue = 0.00157889 * ratio;
the result is 0.002806911838696635. which if computed
5433.001953125 x 0.002806911838696635 = 15.2
so i am wondering why the result becomes 0.04.
Thoughts?
public class Test {
public static void main(String[] args) throws Exception {
PdfReader reader = new PdfReader("src.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("result.pdf"));
Rectangle location = new Rectangle(426.582f, 514.291f, 559.0f, 613.818f);
float[] floats = new float[] {
427.582f, 582.873f,
493.036f, 515.291f,
558.0f, 554.237f,
527.4f, 612.818f,
464.727f, 564.709f,
427.582f, 582.873f
};
PdfArray pdfVertices= new PdfArray(floats);
float calib = 0.002806911838696635f;
PdfAnnotation stamp = PdfAnnotation.createPolygonPolyline(stamper.getWriter(),
location, "15.2 sq cm", true, new PdfArray(pdfVertices));
stamp.setColor(BaseColor.RED);
stamp.setBorderStyle(new PdfBorderDictionary(1, PdfBorderDictionary.STYLE_SOLID));
stamp.put(PdfName.SUBTYPE, PdfName.POLYGON);
stamp.put(new PdfName("IT"), new PdfName("PolygonDimension"));
stamp.put(PdfName.MEASURE, createMeasureDictionary(calib));
stamper.addAnnotation(stamp, 1);
stamper.close();
reader.close();
}
private static PdfDictionary createMeasureDictionary(float pdfCalibrationValue) {
String unit = "cm";
PdfDictionary measureDictionary = new PdfDictionary();
measureDictionary.put(PdfName.TYPE, PdfName.MEASURE);
measureDictionary.put(PdfName.R, new PdfString("1 " + unit + " = 1 " + unit));
PdfDictionary xDictionary = new PdfDictionary();
xDictionary.put(PdfName.TYPE, PdfName.NUMBERFORMAT);
xDictionary.put(PdfName.U, new PdfString(unit));
xDictionary.put(PdfName.C, new PdfNumber(pdfCalibrationValue));
PdfArray xarr = new PdfArray();
xarr.add(xDictionary);
measureDictionary.put(PdfName.X, xarr);
PdfDictionary dDictionary = new PdfDictionary();
dDictionary.put(PdfName.TYPE, PdfName.NUMBERFORMAT);
dDictionary.put(PdfName.U, new PdfString(unit));
dDictionary.put(PdfName.C, new PdfNumber(1));
PdfArray darr = new PdfArray();
darr.add(dDictionary);
measureDictionary.put(PdfName.D, darr);
PdfDictionary aDictionary = new PdfDictionary();
aDictionary.put(PdfName.TYPE, PdfName.NUMBERFORMAT);
aDictionary.put(PdfName.U, new PdfString("sq " + unit));
aDictionary.put(PdfName.C, new PdfNumber(1));
PdfArray aarr = new PdfArray();
aarr.add(aDictionary);
measureDictionary.put(PdfName.A, aarr);
return measureDictionary;
}
}
You have calculated a factor to translate the areas:
the result is 0.002806911838696635. which if computed
5433.001953125 x 0.002806911838696635 = 15.2
But then you use this factor meant for areas unchanged as conversion factor in the X number format array.
The X number format array is the number format array for measurement of change along the x axis and, if Y is not present, along the y axis as well.
Thus, as you don't have a Y entry, your factor for areas must be the conversion factor in X squared!
In other words, use the square root of your area conversion factor as X conversion factor, i.e. replace
float calib = 0.002806911838696635f;
by
float calib = (float)Math.sqrt(0.002806911838696635);
The result now is much better:
But it is not exactly your 15.2 cm². Thus, I checked your numbers, and indeed, your value of 5433.001953125 for the polygone area is slightly off, it should be around 5388.9613.
Using this more correct value I replaced the line above again, this time by:
float calib = (float)Math.sqrt(15.2/5388.96);
and the result:
I have a devexpressgridcontrol. I want to use in one column of the grid : repositoryLookUpEdit.
I fill repositoryLookUpEdit with database question.
This question return three columns : IdPerson , Name and IdCity. Colums : IdPerson and Name have data but IdCity I have to set in appication.
So
- in gridcontrol the column Idcity has fildename : IdCity, and columnEdit : repositoryLookUpEdit.
- repositoryLookUpEdit has DisplayValue : CityName, and ValueMember: IdCity.
And my question is:
When I choose in grid in one row value of city and I go to another row, the value from the first row disaper.
What am I doing wrong? Could you give me some advise?
I use Devexpress 9.2.
this.gvPerson = new DevExpress.XtraGrid.Views.Grid.GridView();
this.replueCity = new DevExpress.XtraEditors.Repository.RepositoryItemLookUpEdit();
this.replueCity.Columns.AddRange(new DevExpress.XtraEditors.Controls.LookUpColumnInfo[] { new DevExpress.XtraEditors.Controls.LookUpColumnInfo("IdCity", "IdCity", 20, DevExpress.Utils.FormatType.None, "", false, DevExpress.Utils.HorzAlignment.Default), new DevExpress.XtraEditors.Controls.LookUpColumnInfo("CityName", "CityName")});
this.replueCity.DisplayMember = "CityName";
this.replueCity.Name = "replueCity";
this.replueCity.NullText = "[Choose city]";
this.replueCity.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.Standard;
this.replueOceny.ValueMember = "IdCity";
// CityColumn this.CityColumn.AppearanceCell.Options.UseTextOptions = true;
this.CityColumn.AppearanceCell.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.CityColumn.AppearanceCell.TextOptions.VAlignment = DevExpress.Utils.VertAlignment.Center;
this.CityColumn.Caption = "Ocena";
this.CityColumn.ColumnEdit = this.replueCity;
this.CityColumn.FieldName = "IdCity";
this.CityColumn.Name = "IdCityName";
this.CityColumn.Visible = true;
You have to set ValueMember for replueCity (which is the editor in the column). You set it only for replueOceny.
Check string IdCity in all three cases: it must be written exactly the same (mind the caps!).
I am trying to group newly made key values but i'm not getting it to work.
This is the code
Dim result = From v In dc.tbl_voertuigs
Join tv In dc.tbl_type_voertuigs On tv.pk_type_voertuig Equals v.fk_type_voertuig
Join tbc In dc.tbl_tebehalencertificaats On tbc.pk_tebehalencertificaat Equals v.fk_tebehalencertificaat
Where tbc.naam_certificaat = subquery2
Select New Voertuig With
{
.p_voertuigid = v.fk_type_voertuig,
.p_voertuigomschr = tv.type + " -- " + tv.merk
}
I would like to group on .p_voertuigid. I already tried some options without any result. I hope someone here can help me.
Thanks in advance!
I think i am almost there, but now i'm getting a new exception:
Value of type system.collections.generic.list(of <anonymoustype>) cannot be converted
to system.collections.generic.list(of tbl_voertuig)
This is my new code
Dim result = (From v In dc.tbl_voertuigs
Join tv In dc.tbl_type_voertuigs On tv.pk_type_voertuig Equals v.fk_type_voertuig
Join tbc In dc.tbl_tebehalencertificaats On tbc.pk_tebehalencertificaat Equals v.fk_tebehalencertificaat
Where tbc.naam_certificaat = subquery2
Group By v = New Voertuig With
{
.p_voertuigid = v.fk_type_voertuig,
.p_voertuigomschr = tv.type + " -- " + tv.merk
} Into grp = Group).ToList
Return result
I found the answer, this is the final code and it works
Dim result = From v In dc.tbl_voertuigs
Join tv In dc.tbl_type_voertuigs On tv.pk_type_voertuig Equals v.fk_type_voertuig
Join tbc In dc.tbl_tebehalencertificaats On tbc.pk_tebehalencertificaat Equals v.fk_tebehalencertificaat
Where tbc.naam_certificaat = subquery2
Group By v = New Voertuig With
{
.p_voertuigid = v.fk_type_voertuig,
.p_voertuigomschr = tv.type + " -- " + tv.merk
} Into grp = Group _
Select v
Return result.ToList
I hope this can help someone who has the same problem in the future
Grtz
Yannick
Is there a way to increment a value in a map without needing a second variable?
for example, this doesn't work:
counts = new Map<string,integer>();
counts.put('month_total',0);
counts.put('month_total',counts.get['month_total']++);
it returns "Initial term of field expression must be a concrete SObject: MAP"
instead I needed to do:
counts = new Map<string,integer>();
counts.put('month_total',0);
integer temp = 0;
temp++;
counts.put('month_total',temp);
is there any way to increment without needing an extra variable?
Replace
counts.put('month_total',counts.get['month_total']++);
with
counts.put('month_total',counts.get('month_total')++);
List<String> lststrings = new List<String>{'key','wewe','sdsd','key','dfdfd','wewe'};
Map<String,Integer> mapval = new Map<String,Integer>();
Integer count = 1;
for(string str : lststrings){
IF(mapval.containsKey(str)){
mapval.put(str,mapval.get(str)+1);
}
else{
mapval.put(str,count);
}
}
system.debug('value of mapval'+mapval);
Hi Need some help with LINQ query.
I have entity called Shift. This entity has several value field but the ones I am intressted in are ShiftID (int), ShiftDate (DateTime) and GrossMount (decimal(10,2). And this needs to be grouped by month (binding this to a graph in ASP.NET).
I need data for the last 12 months grouped by month.
I have come a bit on the way with this post: Linq to Entity, selecting group without value but not quite all the way.
This is my code for now:
public IQueryable<Shift> GetPastMonths(int months, string accountNumber)
{
_context = new EtaxiEnteties();
var _date = DateTime.Today;
var _firstOfMonth = new DateTime(_date.Year, _date.Month, 31);
var _twelveMonthAgoFirstOfMonth = _firstOfMonth.AddMonths(-12);
// Generate a collection of the months and years for the last 12 months
var _monthYears = Enumerable.Range(-12, 12).Select(monthOffset => { var monthDate = _firstOfMonth.AddMonths(monthOffset); return new { y = monthDate.Year, m = monthDate.Month }; });
var _data = (from _monthYear in _monthYears
join _i in
(from _i in _context.Shifts.Where(acc => acc.Account.AccountNumber == accountNumber)
where _i.ShiftDate >= _twelveMonthAgoFirstOfMonth && _i.ShiftDate < _firstOfMonth
group _i by new { y = _i.ShiftDate.Year, m = _i.ShiftDate.Month } into g
select new { ShiftID = g.Key, GrossAmount = g.Count() }) on _monthYear equals _i.ShiftID into j
from _k in j.DefaultIfEmpty()
select new Shift() { ShiftDate = new DateTime(_monthYear.y, _monthYear.m, 1), GrossAmount = _k != null ? _k.GrossAmount : 0 });
return _data as IQueryable<Shift>;
}
Now I have in return a collection of Shift objects, grouped by month but still missing the GrossAmount. Althoug i would need this from today date (only getting from 1 of current month).
Believe this is my main problem: GrossAmount = g.Count(), but I am not sure
Any LINQ specialist out there that could give me a push?
Use GrossAmount = g.Sum(x => x.GrossAmount) to calculate total GrossAmount value of grouped Shift entities. I believe you have typo in GrossAmount (GrossMount) property name.