I have a entity called StockDetails using Entity Framework, see picture below
I want to fetch a list IEnumerable<StockDetail>, summarized by Reels, Qtyton, average date from Days (datetime) and grouping by the rest of the properties.
I’m building a datalayer (WCF Services) with Entity Framework as ORM, some of the services are old SQL queries I’m trying to convert to linq/lamdba expression. But I’m pretty new to how to write and want some help.
This is how I started the query in lambda, but I got stuck on the groupby/sum/average part.
public IEnumerable<StockDetail> ListStockDetailByCustomerNumber(int customerNumber)
{
var CustNo = customerNumber.ToString();
return _entities.StockDetails
.Where(x => x.Custno == CustNo)
.GroupBy(
x =>
new
{
x.Millcd,
x.Matercd,
x.Proddesc,
x.Grammage,
x.Reelwidth,
x.Ordercode,
x.Buyordno,
x.Whsedesc,
x.Co,
x.Finished,
x.Pm,
x.PurchaseOrder,
x.Diameter,
x.Rtadate,
x.Custno,
x.Reels,
x.Days,
x.Qtyton
})
.ToList();
}
Question solved:
public IEnumerable<StockDetail> ListStockDetailByCustomerNumber(int customerNumber)
{
var stockDetailsList = new List<StockDetail>();
var custNo = customerNumber.ToString();
var list = _entities.StockDetails
.Where(x => x.Custno == custNo )
.GroupBy(
x =>
new
{
x.Millcd,
x.Matercd,
x.Proddesc,
x.Grammage,
x.Reelwidth,
x.Ordercode,
x.Buyordno,
x.Whsedesc,
x.Co,
x.Finished,
x.Pm,
x.PurchaseOrder,
x.Diameter,
x.Rtadate,
x.Custno,
x.UpdDte
})
.Select(x => new
{
x.Key.Millcd,
x.Key.Matercd,
x.Key.Proddesc,
x.Key.Grammage,
x.Key.Reelwidth,
x.Key.Ordercode,
x.Key.Buyordno,
Reels = x.Sum(p => p.Reels),
Qtyton = x.Sum(p => p.Qtyton),
Day = x.Max(p => p.Days),
//Day = x.Average(p => p.Days.Ticks), // Want to calculate average datetime of date but linq dosn't support datetime.ticks
x.Key.Whsedesc,
x.Key.Co,
x.Key.Finished,
x.Key.Pm,
x.Key.PurchaseOrder,
x.Key.Diameter,
x.Key.Rtadate,
x.Key.Custno,
x.Key.UpdDte
});
foreach (var s in list)
{
stockDetailsList.Add(new StockDetail
{
Millcd = GetFriendlyNameForKey(s.Millcd),
Matercd = s.Matercd,
Proddesc = s.Proddesc,
Grammage = s.Grammage,
Reelwidth = s.Reelwidth,
Ordercode = s.Ordercode,
Buyordno = s.Buyordno,
Reels = s.Reels,
Qtyton = s.Qtyton,
Days = s.Day,
Whsedesc = s.Whsedesc,
Co = s.Co,
Finished = s.Finished,
Pm = s.Pm,
PurchaseOrder = s.PurchaseOrder,
Diameter = s.Diameter,
Rtadate = s.Rtadate,
Custno = s.Custno,
UpdDte = s.UpdDte
});
}
return stockDetailsList;
}

This is how the query looks in T-SQL
SELECT
Millcd, Matercd,
Proddesc, Grammage,
Reelwidth, Ordercode,
Buyordno,
SUM(Reels) as Reels,
SUM(Qtyton) as Qtyton,
Whsedesc, Co,
(cast(FLOOR(avg(cast(DateProd as float))) as datetime)) As Days,
Finished, Pm,
PurchaseOrder,
Diameter, Rtadate,
Custno, UpdDte
FROM StockDetail
WHERE custno = @custcode
GROUP BY Millcd, Matercd, Proddesc, Grammage, Reelwidth, Ordercode, Buyordno,
Whsedesc, Co, Finished, Pm, PurchaseOrder, Diameter, Rtadate, Custno, UpdDte
not sure if this will help you but you can add
instead of
x.Reelsin your select , and do the same withQtytonFor your average use the average extension
your select will look something like
.Select(x=>new {...})after your where statement then the group by