How to use group by with multiple table joins in Entity framework core - join

I am trying to convert below query in entity framework core but not able to access field in select query after apply group by.
Select ProdCatg.Category As [Category]
,Prod.FKProdCatgID As [FKProdCatgID]
,SUM(Dtl.Qty + LD.ProdConv1 + Trn.CashAmt ) As [DistributionRateValue]
From tblSalesInv_Dtl Dtl
Left Join tblSalesInv_Trn Trn on Trn.PKID=Dtl.FKID And Trn.FKSeriesID=Dtl.FKSeriesID
Left Join tblProdLot_Dtl LD on Dtl.FKLotID=LD.PKLotID And LD.FKProdID=Dtl.FKProdID
Left Join tblProd_Mas Prod ON PKProdID=Dtl.FKProdID
Left Join tblProdCatg_Mas ProdCatg On PKProdCatgID=Prod.FKProdCatgID
Where Trn.DraftMode=0
Group By Prod.FKProdCatgID,ProdCatg.Category
Order By Category
I am trying convert like this but but not able to access Dtl.Qty + LD.ProdConv1 + Trn.CashAmtfields
var result1 = (from dtl in _context.TblSalesInvDtl
join ser in lstSeries on dtl.FkseriesId equals ser
join trn in _context.TblSalesInvTrn on new { s1 = dtl.Fkid, s2 = ser } equals new { s1 = trn.Pkid, s2 = trn.FkseriesId }
join lot in _context.TblProdLotDtl on new { s1 = dtl.FklotId, s2 = dtl.FkprodId } equals new { s1 = lot.PklotId, s2 = lot.FkprodId }
join p in _context.TblProdMas on dtl.FkprodId equals p.PkprodId into pr
from Prod in pr.DefaultIfEmpty()
join pl in _context.TblProdMas on dtl.FklinkedProdId equals pl.PkprodId into plid
from ProdLinked in plid.DefaultIfEmpty()
join t in _context.TblTaxMas on dtl.FktaxId equals t.PktaxId into tid
from Tax in tid.DefaultIfEmpty()
join c in _context.TblProdCatgMas on Prod.FkprodCatgId equals c.PkprodCatgId into cid
from Catg in cid.DefaultIfEmpty()
where trn.EntryDate == Convert.ToDateTime("1-12-2018")
group Catg by new { Prod.FkprodCatgId, Catg.Category } into gb
//, dtl, lot, Prod
select new
{
CategoryName = gb.FirstOrDefault().Category,
DistributionRateValue = gb.Sum(a => (gb.Key.dtl.Qty + gb.Key.lot.ProdConv1+ gb.Key.lot.CashAmt)),
FKProdCatgID= gb.Key.Prod.FkprodCatgId,
}
).ToList();
can anybody help me how can I access multiple table fields in sum with groupby in entity framework core.

Related

Need help converting SQL into LINQ

SELECT ra.ResidentID, ra.RoomID, r.Number, ra.StartDate, p.FacilityID
FROM(
SELECT ResidentID, MAX(StartDate) AS max_start
FROM RoomAssignments
GROUP BY ResidentID
) m
INNER JOIN RoomAssignments ra
ON ra.ResidentID = m.ResidentID
AND ra.StartDate = m.max_start
INNER JOIN Rooms r
ON r.ID = ra.RoomID
INNER JOIN Person p
ON p.ID = ra.ResidentID
inner join ComplianceStage cs
ON cs.Id = p.ComplianceStageID
ORDER BY ra.EndDate DESC
I'm trying to figure out how to convert this to C# using LINQ. I'm brand new with C# and LINQ and can't get my subquery to fire correctly. Any chance one of you wizards can turn the lights on for me?
Update-----------------
I think I've got the jist of it, but am having trouble querying for the max startdate:
var maxQuery =
from mra in RoomAssignments
group mra by mra.ResidentID
select new { mra.ResidentID, mra.StartDate.Max() };
from ra in RoomAssignments
join r in Rooms on ra.RoomID equals r.ID
join p in Persons on ra.ResidentID equals p.ID
where ra.ResidentID == maxQuery.ResidentID
where ra.StartDate == maxQuery.StartDate
orderby ra.ResidentID, ra.StartDate descending
select new {ra.ResidentID, ra.RoomID, r.Number, ra.StartDate, p.FacilityID}
Following my LINQ to SQL Recipe, the conversion is pretty straight forward if you just follow the SQL. The only tricky part is joining the range variable from the subquery for max start date to a new anonymous object from RoomAssignments that matches the field names.
var maxQuery = from mra in RoomAssignments
group mra by mra.ResidentID into mrag
select new { ResidentID = mrag.Key, MaxStart = mrag.Max(mra => mra.StartDate) };
var ans = from m in maxQuery
join ra in RoomAssignments on m equals new { ra.ResidentID, MaxStart = ra.StartDate }
join r in Rooms on ra.RoomID equals r.ID
join p in Persons on ra.ResidentID equals p.ID
join cs in ComplianceStage on p.ComplianceStageID equals cs.Id
orderby ra.EndDate descending
select new {
ra.ResidentID,
ra.RoomID,
r.Number,
ra.StartDate,
p.FacilityID
};

multilevel linq query with left join

Relations in my query:
relations
Here is my query with normal joins:
var query = from myabonamenty in ArAbonamenty
join nexotowary in Nexo_ARWAL.Asortymenty
on myabonamenty.Nexo_towar equals nexotowary.Id
join myklienci in ArKlienci
on myabonamenty.Id_klient equals myklienci.Id_klient
join nexoodbiorcy in Nexo_ARWAL.Podmioty
on myklienci.Nexo_klient equals nexoodbiorcy.Id
join nexonabywcy in Nexo_ARWAL.Podmioty
on myklienci.Nexo_klient_do_faktur equals nexonabywcy.Id
select new
{
abonament_id = myabonamenty.Id_abonament,
towar=nexotowary.Nazwa,
nabywca= nexonabywcy.NazwaSkrocona,
odbiorca = nexoodbiorcy.NazwaSkrocona
};
How can I make left joins in this query ( myklienci.Nexo_klient -> nexoodbiorcy.Id and myklienci.Nexo_klient_do_faktur->nexonabywcy.Id ) ?
Add into/from/in/DefaultIfEmpty() for the ones that should be left joined:
var query = from myabonamenty in ArAbonamenty
join nexotowary in Nexo_ARWAL.Asortymenty
on myabonamenty.Nexo_towar equals nexotowary.Id
join myklienci in ArKlienci
on myabonamenty.Id_klient equals myklienci.Id_klient
join nexoodbiorcy in Nexo_ARWAL.Podmioty
on myklienci.Nexo_klient equals nexoodbiorcy.Id into nexoodbiorcyg
from nexoodbiorcy in nexoodbiorcyg.DefaultIfEmpty()
join nexonabywcy in Nexo_ARWAL.Podmioty
on myklienci.Nexo_klient_do_faktur equals nexonabywcy.Id into nexonabywcyg
from nexonabywcy in nexonabywcyg.DefaultIfEmpty()
select new
{
abonament_id = myabonamenty.Id_abonament,
towar=nexotowary.Nazwa,
nabywca= nexonabywcy.NazwaSkrocona,
odbiorca = nexoodbiorcy.NazwaSkrocona
};
Depending on the database and LINQ version being used, you may also need to test for null or use the conditional operator for column references for range variables that may be empty:
select new
{
abonament_id = myabonamenty.Id_abonament,
towar=nexotowary.Nazwa,
nabywca= nexonabywcy?.NazwaSkrocona,
odbiorca = nexoodbiorcy?.NazwaSkrocona
};
or
select new
{
abonament_id = myabonamenty.Id_abonament,
towar=nexotowary.Nazwa,
nabywca= (nexonabywcy !=null ? nexonabywcy.NazwaSkrocona : null),
odbiorca = (nexoodbiorcy != null ? nexoodbiorcy.NazwaSkrocona : null)
};

Invalid Expression term Where

I have following LINQ statement:
from o in Orders
join od in OrderDetails on o.OrderNumber equals od.OrderNumber
join r in RMAs on o.OrderNumber equals r.OrderNumber
join rd in RMADetails on r.RMAnumber equals rd.RMAnumber
from i in Inventory
where( a => ( od.SKU == a.LocalSKU)).DefaultIfEmpty()//error is here
where (r.Status != "Pending" && od.Adjustment == false)
select new
{
r.Status,
o.Name,
o.Company,
o.Address,
o.Address2,
o.City,
o.State,
o.Country,
o.Email,
o.Zip,
o.Phone,
o.ShipName,
o.ShipCompany,
o.ShipAddress,
o.ShipAddress2,
o.ShipCity,
o.ShipCountry,
o.ShipState,
o.ShipPhone,
o.ShipZip,
o.OrderNumber,
o.ShippingTotal,
OrderDate = o.OrderDate,
SerialNumbers = rd.SerialNumbers ?? "",
o.SourceOrderID
}
It's giving Invalid Where term. What I want to use LEFT OUTER JOIN having SQL Equivalent left join Inventory i on od.SKU = i.LocalSKU
Try this:
var qry = from o in Orders
join od in OrderDetails.Where(od=>od.Adjustment == false) on o.OrderNumber equals od.OrderNumber
join i in Inventory on i.LocalSKU equals od.SKU into grp
from g in grp.DefaultIfEmpty()
join r in RMAs.Where(r=>r != 'Pending') on o.OrderNumber equals r.OrderNumber
join rd in RMADetails on r.RMAnumber equals rd.RMAnumber
select new
{
//set of columns here
};

Using LinQ with groupby and Max() function

I am trying to write the following query in LINQ syntax:
SELECT Patient.PatientIDA, MAX(TxFieldPoint.EditDttm) AS Expr1
FROM Patient INNER JOIN
TxSite ON Patient.PatientIDA = TxSite.PatientIDA INNER JOIN
TxField ON TxSite.SiteId = TxField.SiteId INNER JOIN
TxFieldPoint ON TxField.FldId = TxFieldPoint.FldId
GROUP BY Patient.PatientIDA
ORDER BY Patient.PatientIDA
and i'm comming up with this:
var PtsList = from pt in dc.Patient
join site in dc.TxSite on pt.PatientIDA equals site.PatientIDA
join fld in dc.TxField on site.SiteId equals fld.SiteId
join fldpnt in dc.TxFieldPoint on fld.FldId equals fldpnt.FldId
group new { pt, fldpnt } by new { fldpnt.EditDttm } into pt_fldpnt
select new cPtData
{
pt_name = pt_fldpnt.FirstOrDefault().pt.LastName,
pt_firstname = pt_fldpnt.FirstOrDefault().pt.FirstName,
pt_hospitalID = pt_fldpnt.FirstOrDefault().pt.PatientIDA,
chart_lasteditdttm = pt_fldpnt.Max(m => m.fldpnt.EditDttm).Value.Date,
};
Based on other posts i've read on this website. It does not work. Help would be much appreciated.

Linq Nested Inner Joins

I want to join the following Tables
1. B_Book[1st Table]
-B_BID (Book ID)(PK)
-B_Name
-B_CategroyID (FK)
2. BI_BookInstance [2nd Table]
-BI_IID(Instance ID)
-BI_BID (FK)
-BI_Price
3. BC_BookCategory [3rd Table]
-BC_CategoryID (PK)
-BC_CategoryName
First Join B_Book and BI_BookInstance then join the result of those both with BookCategory.
(1st join)[B_BID equals BI_BID]
(2nd nested join)[result of 1st join B_CategoryID equals BC_CategoryID]
Edit
SQL would be something like the following:
SELECT * FROM
(SELECT * FROM B_Book b JOIN BI_BookInstance bi on b.B_BID = bi.BI_BID) as t1
JOIN BC_BookCategoryID bc on bc.BC_CategoryID = t1.B_CategoryID
What matches your query in LINQ would be the following (and you'll notice the similarity with SQL). I've also included some examples on how to rename the fields returned, such as Price or CategoryName:
var results = from b in B_Book
join bi in BI_BookInstance
on b.B_BID equals bi.BI_BID
join bc in BC_BookCategory
on b.B_CategoryID equals bc.BC_CategoryID
select new
{
// put in whatever fields you want returned here:
b.B_BID,
b.B_CategoryID,
b.B_Name,
bi.BI_BID,
bi.BI_IID,
Price = bi.BI_Price,
bc.BC_CategoryID,
CategoryName = bc.BC_CategoryName
};
I have supposed inner joins (your FKs is not null), so i would like query like this:
var ctx = new YourEntities();
var query = from b in ctx.B_Book
from bi in ctx.BI_BookInstance
from bc in ctx.BC_BookCategory
where b.B_BID == bi.BI_BID && b.B_CategoryID == bc.BC_CategoryID
select new
{
BInstID = bi.BI_IID,
BName = b.B_Name,
BPrice = bi.BI_Price,
BCategory = bc.BC_CategoryName
};
foreach (var item in query)
{
Console.WriteLine(item.BInstID);
Console.WriteLine(item.BName);
Console.WriteLine(item.BPrice);
Console.WriteLine(item.BCategory);
Console.WriteLine("");
}
You can do this without explicitly using linq's join statement, provided that navigation properties are in place:
from b in ctx.B_Book
from bi in b.BookInstances
select new { b.Property1, bi.Property2, b.BookCategory.Name }

Resources