In the below code I am trying to return a new sequence type that is grouped by the ProductName, Size, and Packaging properties from the original sequence, but instead I get a new type sequence that is ungrouped. What am I missing here?
query{
for row in allDeliveries do
let key = AnonymousObject<_,_,_>(row.ProductName,row.Size,row.Packaging)
groupValBy row key into g
select g
}
|> Seq.map (fun (del) ->
{
POFD = del;
ProductName = del.Key.Item1;
Size = del.Key.Item2;
Packaging = del.Key.Item3;
Quantity = del.Count()
})
This was my solution:
query{
for row in allDeliveries do
groupValBy row (row.ProductName, row.Size, row.Packaging) into g
select {
POFD = g;
ProductName = query{
for row2 in g do
select row2.ProductName
headOrDefault
}
Size = query{
for row2 in g do
select row2.Size
headOrDefault
}
Packaging = query{
for row2 in g do
select row2.Packaging
headOrDefault
}
Quantity = g.Count()
}
}
Related
Let's suppose we have a Linq query like this:
int companyID = Convert.ToInt32(((UserIdentity)User.Identity).CompanyId);
var stock = from i in _stockService.GetStock()
join ur in _inventoryService.GetInventory() on i.ProductID equals ur.Id
where ur.ComapnyId == companyID
select new StockVM
{
Product = ur.ItemName,
Quantity = i.Quantity,
BatchID = i.BatchID,
StockStatus = i.StockStatus,
MfgDate = i.MfgDate,
ExpDate = i.ExpDate,
};
Result
How to do a "Group By Product" with sum of Quantity in this linq query?
I need to only get max ExpDate firstOrDefault
try something like this:
int companyID = Convert.ToInt32(((UserIdentity)User.Identity).CompanyId);
var stock = from i in _stockService.GetStock()
join ur in _inventoryService.GetInventory() on i.ProductID equals ur.Id
where ur.ComapnyId == companyID
group new { Quantity = i.Quantity } by new { ur.ItemName } into g
select new { Product = g.Key, TotalQuantity = g.Sum() } ).ToList() ;
List<StockVM> _lst = new List<StockVM>();
foreach(var item in stock ){
StockVM row = new StockVM();
row.Product = item.ItemName;
//....
_lst.Add(row);
}
I have a controller that accepts a list of strings. THese strings essentially are IDs that a user selects on the view. I need to build the model based upon fields from to tables, hence the need for the join. The bellow code will not build as it claims the properties from the joined table do not exist. It only accepts table 1 values. Item.Well_No and Item.Well_Name throw the error. These are included in the "y" table that i joined to "x"..
[HttpPost]
public ActionResult buildSelectionTable(List<string> dta)
{
var a = from x in db._AGREEMENTS
join y in db.WELL_AGMT_XREF on x.AGMT_NUM equals y.AGMT_NUM
where dta.Contains(x.AGMT_NUM)
select x;
List<AgmtModel> model = new List<AgmtModel>();
foreach (var item in a)
{
model.Add(new AgmtModel { Agmt_Name = item.AGMT_NAME, Agmt_Num = item.AGMT_NUM, Agmt_Type = item.AGMT_TYPE_DESCR, Amnt_Status = item.AGMT_STAT_DESCR, Company = item.CO_NAME, DaysToExp = item.DaysToExp, Drs_Url = item.DRS_URL, Effective_Date = item.EFF_DT, Orig_Lessee = item.ORIG_LESSEE, Prop_Status = item.AGMT_PROP_STAT_DESCR, Expiration_Date = item.EXPR_DATE, Acreage = item.LGL_AREA, Extention_Expiration = item.EXTN_EXPR_DT, WellNo = item.WELL_NO, Well_Name = item.WELL_NAME });
}
return PartialView("_SelectionTable", model);
}
You are only selecting x in your query you need to also select y and reference it.
change select x to be select new { x, y}
and then
foreach (var item in a)
{
model.Add(new AgmtModel { Agmt_Name = item.y.AGMT_NAME, Agmt_Num = item.x.AGMT_NUM ... });
}
you need to insert .x or .y before you the field to determine the field names
alternatively you could actually put the constructor directly in the query
so instead of select x
select new AgmtModel { Agmt_Name = y.AGMT_NAME, etc...}
then you can just return PartialView("_SelectionTable", a.ToList())
I want to return multiple column in join result and fill in view model(VMFoodFoodMeal).
for example I want to fill VMFoodFoodMeal by Join result
Thanks
IEnumerable<VMFoodFoodMeal> _fmt = (from e in db.FoodProgramMealFood
join j in db.Foods on e.FoodId equals j.Id
select new
{
Id = e.Id,
Name = j.Name,
});
It is hard to understand what you want, but as example you can look here at Group Join section.
Here is an example code from there:
public void Linq103()
{
string[] categories = new string[]{
"Beverages",
"Condiments",
"Vegetables",
"Dairy Products",
"Seafood" };
List<Product> products = GetProductList();
var q =
from c in categories
join p in products on c equals p.Category into ps
select new { Category = c, Products = ps };
foreach (var v in q)
{
Console.WriteLine(v.Category + ":");
foreach (var p in v.Products)
{
Console.WriteLine(" " + p.ProductName);
}
}
}
result:
Beverages:
Chai
Chang
Guaraná Fantástica
Sasquatch Ale
Steeleye Stout
Côte de Blaye
Chartreuse verte
Ipoh Coffee
...
if you want to send your join Result to a model without using foreach statement you have to use this code
IEnumerable<VMFoodFoodMeal> _fmt = (from e in db.FoodProgramMealFood
join j in db.Foods on e.FoodId equals j.Id
select new VMFoodFoodMeal()
{
Id = e.Id,
Name = j.Name,
});
for example in above code I had a view model (VMFoodFoodMeal) and want to fill it by join result.
I have to make new instance of my model in select and then fill its property.
Thanks
I would like to end up with a list where my categories are grouped according to the users id.
IEnumerable<JoinClass> catList =
from c in db.Users2
join e in db.Categories on c.Id_Users equals e.FK_Users
where c.EEID == UserEEID
group e.Category by c.EEID in z
select new JoinClass
{
Category = e.Category,
EEID = c.EEID,
};
return View(catList.ToList() );
IEnumerable<JoinClass> catList =
from c in db.Users2
join e in db.Categories on c.Id_Users equals e.FK_Users
where c.EEID == UserEEID
group e.Category by c.EEID in z
select new JoinClass
{
Categories = z.ToList(),
EEID = z.Key,
};
return View(catList.ToList() );
Assuming you ACTUALLY meant to find all Categories for each EEID.
Model:
return (from m in meterReadings
group m by new { date = m.ReadDate } into g
select new
{
ReadDate = g.Key.date.ToString("dd.MM.yyyy - HH:mm:ss"),
T1 = from t1 in g
where t1.Name == "T1"
select t1.Value.ToString("0,0.000"),
T2 = from t2 in g
where t2.Name == "T2"
select t2.Value.ToString("0,0.000"),
T3 = from t3 in g
where t3.Name == "T3"
select t3.Value.ToString("0,0.000"),
Total = from total in g
where total.Name == "Toplam"
select total.Value.ToString("0,0.000")
}).AsQueryable<object>();
Query
var table = MeterReadingManager.GetMeterReadingsPivot(meterReadings, 1);
//No Error (in title)
rows = table.OrderBy("ReadDate","desc").Skip((pageIndex) * pageSize).Take(pageSize)
//Error (in title)
rows = table.OrderBy("T1","desc").Skip((pageIndex) * pageSize).Take(pageSize)
When I order by ReadDate, It works. But When I try to order by other fields I get the error : At least one object must implement IComparable
Why I get this error? And How can I fix it?
If you want to sort a list of items of any type, the type must implement IComparable for the sort algorithm to be able to compare items. T1 is an IQueryable, whcih does not implement IComparable. I think you intended to create string values for T1, T2, and T3. If so, you should add FirstOrDefault() to each linq statement creating T1, etc.
Edit
(After your comment)
I mean this:
T1 = (from t1 in g
where t1.Name == "T1"
select t1.Value.ToString("0,0.000")).FirstOrDefault()
Now T1 is a string and, thus, it can be used in sorting.
You could try ThenByDescending:
var rows = table
.OrderByDescending(x => x.ReadDate).Skip((pageIndex) * pageSize).Take(pageSize)
.ThenByDescending(x => x.T1).Skip((pageIndex) * pageSize).Take(pageSize);
UPDATE:
You could use Reflection (a bit slower) if ordering by one field:
var tableInfo = table.GetType().GetProperty("T1");
var sortedRow = table.OrderByDescending(x => tableInfo.GetValue(x, null)).Skip((pageIndex) * pageSize).Take(pageSize);