Need help converting SQL into LINQ - 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
};

Related

Convert SQL to LINQ with multiple types of joins

I need to convert a SQL query into LINQ, either to Query Syntax or Method Syntax.
SELECT
IA.ItemId,
IVT.ItemName,
C.DeliveryMethod,
SUM(OD.Quantity) AS Qty
FROM OrderHeader OH
INNER JOIN OrderDetail OD ON OH.OrderId = OD.OrderId
LEFT JOIN Customer C ON OH.CustomerId = C.Id
LEFT JOIN ItemAvailability IA ON OD.ItemId = IA.RecId
INNER JOIN Inventory IVT ON IA.ItemId = IVT.ItemId
WHERE OH.DeliveryDate = '02/03/2023'
AND OH.OrderType = 'Web'
GROUP BY IA.ItemId, Ivt.ItemName, C.DlvMode
ORDER BY IA.ItemId
I've spent a long time Googling and YouTubing, but everyone provides examples of either just Inner Joins, Group Joins, or Left Joins. No one gave example of having both Inner Joins and Left Joins in the same query.
I know the syntax for a simple inner join like this:
SQL
SELECT OH.OrderId, OD.ItemId, OD.Quantity
FROM OrderHeader OH
INNER JOIN OrderDetail OD ON OH.OrderId = OD.OrderId
ORDER BY OD.ItemId
LINQ
from oh in OrderHeader
join od in OrderDetail on oh.OrderId equals od.OrderId
orderby ordt.IItemId
select new {
OrderId = oh.OrderId,
ItemId = od.ItemId,
Quantity = od.Quantity
}
And I know the LINQ syntax for left join also. But I am having trouble to figure out how to have both inner and left joins in one LINQ query.
I hope someone here can help, please.
Just combine join techniques together
var deliveryDate = ...;
var query =
from oh in OrderHeader
join od in OrderDetail on oh.OrderId equals od.OrderId
join c in Customer ON oh.CustomerId equals c.Id into cj
from c in cj.DefaultIfEmpty()
join ia in ItemAvailability on od.ItemId equals ia.RecId into iaj
from ia in iaj.DefaultIfEmpty()
join ivt in Inventory on ia.ItemId equals ivt.ItemId
where oh.DeliveryDate == deliveryDate && oh.OrderType == "Web"
group od by new { ia.ItemId, ivt.ItemName, c.DlvMode, c.DeliveryMethod } into g
select new
{
g.Key.ItemId,
g.Key.DeliveryMethod,
Qty = g.Sum(x => x.Quantity)
} into s
orderby s.ItemId
select s;

Which is best way to represent huge data using Web.API?

Case1:
var query = (from p in db.TblPost where (from q in db.TblThread
where q.LocationLocationid == locationID && q.CategoriesCategoryid == categoryID select q.Threadid).Contains(p.ThreadThreadid)
join r in db.TblThread on p.ThreadThreadid equals r.Threadid join s in db.TblUser on p.UserUserid equals s.Userid join t
in db.TblCategories on r.CategoriesCategoryid equals t.Categoryid join u in db.TblLocation on r.LocationLocationid
equals u.Locationid orderby r.CreatedTime descending
select new { p, r.Subject, r.EventAddress, r.EventClosetime, r.EventDate, r.EventDuration, r.EventStarttime,
r.EventTitle, r.IseventAllday, r.TargetUsers, r.CreatedTime, s.FirstName, s.MiddleName, s.LastName, t.Name,
u.Locationname, r.Isreadonly }).ToList();
OR
Case 2:
List<TblPost> _tblPost = new List<TblPost>();
_tblPost = (from p in db.TblPost select p).ToList();
List<TblThread> _tblThread = new List<TblThread>();
_tblThread = (from p in db.TblThread select p).ToList();
List<TblUser> _tblUser = new List<TblUser>();
_tblUser = (from p in db.TblUser select p).ToList();
List<TblLocation> _tblLocation = new List<TblLocation>();
_tblLocation = (from p in db.TblLocation select p).ToList();
List<TblCategories> _tblCategory = new List<TblCategories>();
_tblCategory = (from p in db.TblCategories select p).ToList();
var query = (from p in _tblPost where (from q in _tblThread where q.LocationLocationid == locationID
&& q.CategoriesCategoryid == categoryID select q.Threadid).Contains(p.ThreadThreadid) join r in _tblThread on p.ThreadThreadid
equals r.Threadid join s in _tblUser on p.UserUserid equals s.Userid join t in _tblCategory on r.CategoriesCategoryid equals
t.Categoryid join u in _tblLocation on r.LocationLocationid equals u.Locationid orderby r.CreatedTime descending
select new { p, r.Subject, r.EventAddress, r.EventClosetime, r.EventDate, r.EventDuration, r.EventStarttime,
r.EventTitle, r.IseventAllday, r.TargetUsers, r.CreatedTime, s.FirstName, s.MiddleName, s.LastName,
t.Name, u.Locationname, r.Isreadonly }).ToList();
I've these two codes which results the same. But, in case 2 i'm getting the result some quickly as compared to case 1. Which one should i need to follow?
Shall i follow case 2? is it right way to get huge data in Web.API?

complex t-sql to linq query: inner join, group by, select

I'm trying to build a linq query based on this:
select
SERVICE_REQUEST_CR.SRCR_FK_SR, SERVICE_REQUEST.SR_TX_NAME,
AC_USER.USER_TX_NAME, SERVICE_REQUEST_CR.SRCR_DT_CREATED,
SERVICE_REQUEST_CR_STATUS.SRCRST_TX_DESCRIPTION,
COUNT(SERVICE_REQUEST_PROGRAM.SRPG_FK_SR_ID) as Activities
from
SERVICE_REQUEST_CR
inner join
AC_USER on AC_USER.USER_ID = SERVICE_REQUEST_CR.SRCR_FK_REQUESTOR
inner join
SERVICE_REQUEST_CR_STATUS on SERVICE_REQUEST_CR_STATUS.SRCRST_ID = SERVICE_REQUEST_CR.SRCR_FK_CR_STATUS
inner join
SERVICE_REQUEST on SERVICE_REQUEST.SR_ID = SERVICE_REQUEST_CR.SRCR_FK_SR
inner join
SERVICE_REQUEST_PROGRAM on SERVICE_REQUEST_PROGRAM.SRPG_FK_SR_ID = SERVICE_REQUEST_CR.SRCR_FK_SR
group by
SERVICE_REQUEST_CR.SRCR_FK_SR, SERVICE_REQUEST.SR_TX_NAME,
AC_USER.USER_TX_NAME, SERVICE_REQUEST_CR.SRCR_DT_CREATED,
SERVICE_REQUEST_CR_STATUS.SRCRST_TX_DESCRIPTION,
SERVICE_REQUEST_PROGRAM.SRPG_FK_SR_ID
This is as far as I could come up with:
Dim x = From cr In db.SERVICE_REQUEST_CR
Join usr In db.AC_USER On usr.USER_ID Equals cr.SRCR_FK_REQUESTOR
Join crSt In db.SERVICE_REQUEST_CR_STATUS On crSt.SRCRST_ID Equals cr.SRCR_FK_CR_STATUS
Join sr In db.SERVICE_REQUEST On sr.SR_ID Equals cr.SRCR_FK_SR
Join srProg In db.SERVICE_REQUEST_PROGRAM On srProg.SRPG_FK_SR_ID Equals cr.SRCR_FK_SR
Could anyone give me a help with this? It's the grouping that gets confusing so I just put the joins and the query to keep it simple.
Thanks,
Something like this, but I am not sure about Basic syntax:
Dim x = From cr In db.SERVICE_REQUEST_CR
Join usr In db.AC_USER On usr.USER_ID Equals cr.SRCR_FK_REQUESTOR
Join crSt In db.SERVICE_REQUEST_CR_STATUS On crSt.SRCRST_ID Equals cr.SRCR_FK_CR_STATUS
Join sr In db.SERVICE_REQUEST On sr.SR_ID Equals cr.SRCR_FK_SR
Join srProg In db.SERVICE_REQUEST_PROGRAM On srProg.SRPG_FK_SR_ID Equals cr.SRCR_FK_SR
group new
{
cr.SRCR_FK_SR,
sr.SR_TX_NAME,
usr.USER_TX_NAME,
cr.SRCR_DT_CREATED,
crSt.SRCRST_TX_DESCRIPTION,
srProg.SRPG_FK_SR_ID
}
by new
{
cr.SRCR_FK_SR,
sr.SR_TX_NAME,
usr.USER_TX_NAME,
cr.SRCR_DT_CREATED,
crSt.SRCRST_TX_DESCRIPTION,
srProg.SRPG_FK_SR_ID
} into gr
select new
{
gr.Key.SRCR_FK_SR,
gr.Key.SR_TX_NAME,
gr.Key.USER_TX_NAME,
gr.Key.SRCR_DT_CREATED,
gr.Key.SRCRST_TX_DESCRIPTION,
gr.Key.SRPG_FK_SR_ID,
Activities = gr.Count()
}

How to select first row of each id linq

So I have few tables and i want inner join it information two create
new object. But I have a little bit trouble.
One my table have connection one to many, and when linq request , it
give me more result than i want , he just copy information. I need
request something like this:
IPagedList<HelperListings> srch = (from l in db.gp_listing
where l.DateCreated > weekago
join lp in db.gp_listing_photo on l.Id equals lp.ListingId
join loc in db.gp_location on l.LocationId equals loc.Id
orderby l.DateCreated ascending
select new HelperListings { id = l.Id, HouseNumber = l.HouseNumber,ListingPrice = l.ListingPrice, PhotoUrl = lp.PhotoUrl.First(), AreaStateCode = loc.AreaStateCode }).ToList().ToPagedList(page ?? 1, 15);
PhotoUrl = lp.PhotoUrl.First() i need something like this but i don`t have any ideas how to do it. Need ur help guys.
UPDATE :
Responding to your comment, you have at least 2 options : 1. use group by and select only the first PhotoUrl from each group, or 2. don't join to gp_listing_photo table to avoid duplicated rows, and use subquery to get only the first PhotoUrl. Example for the latter :
IPagedList<HelperListings> srch =
(from l in db.gp_listing
where l.DateCreated > weekago
join loc in db.gp_location on l.LocationId equals loc.Id
orderby l.DateCreated ascending
select new HelperListings
{
id = l.Id,
HouseNumber = l.HouseNumber,
ListingPrice = l.ListingPrice,
PhotoUrl = (from lp in db.gp_listing_photo where l.Id = lp.ListingId select lp.PhotoUrl).FirstOrDefault(),
AreaStateCode = loc.AreaStateCode
}
).ToList().ToPagedList(page ?? 1, 15);
How about simply appending .Distinct() after your LINQ query to avoid duplicated data :
IPagedList<HelperListings> srch =
(from l in db.gp_listing
where l.DateCreated > weekago
join lp in db.gp_listing_photo on l.Id equals lp.ListingId
join loc in db.gp_location on l.LocationId equals loc.Id
orderby l.DateCreated ascending
select new HelperListings
{
id = l.Id,
HouseNumber = l.HouseNumber,
ListingPrice = l.ListingPrice,
PhotoUrl = lp.PhotoUrl,
AreaStateCode = loc.AreaStateCode
}
).Distinct().ToList().ToPagedList(page ?? 1, 15);
For Reference : LINQ Select Distinct with Anonymous Types

Joining three tables and using a left outer join

I have three tables. Two of them join equally but one will need to join with a left. I'm finding a lot of code to do this in linq but between two tables only.
Here is the SQL code that I'm trying to re-code within LINQ.
SELECT PRSN.NAME
,CO.NAME
,PROD.NAME
FROM PERSON PRSN
INNER JOIN COMPANY CO ON PRSN.PERSON_ID = CO.PERSON_ID
LEFT OUTER JOIN PRODUCT PROD ON PROD.PERSON_ID = PROD.PERSON_ID;
Here is a snippet of LINQ code that I'm using as a base. I'm just not able to piece together the third table (product in my sample SQL) via LINQ and with a left outer join. The sample is between two tables. Thanks for any tips.
var leftOuterJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from item in prodGroup.DefaultIfEmpty(new Product{Name = String.Empty, CategoryID = 0})
select new { CatName = category.Name, ProdName = item.Name };
Michael
How about this:
var loj = (from prsn in db.People
join co in db.Companies on prsn.Person_ID equals co.Person_ID
join prod in db.Products on prsn.Person_ID equals prod.Person_ID into prods
from x in prods.DefaultIfEmpty()
select new { Person = prsn.NAME, Company = co.NAME, Product = x.NAME })
EDIT: if you want to do a left outer join on all tables, you can do it like this:
var loj = (from prsn in db.People
join co in db.Companies on prsn.Person_ID equals co.Person_ID into comps
from y in comps.DefaultIfEmpty()
join prod in db.Products on prsn.Person_ID equals prod.Person_ID into prods
from x in prods.DefaultIfEmpty()
select new { Person = prsn.NAME, Company = y.NAME, Product = x.NAME })
Taken from another Stackoverflow thread somewhere, there's a more legible way to do this:
var loj = (from prsn in db.People
from co in db.Companies.Where(co => co.Person_ID == prsn.Person_ID).DefaultIfEmpty()
from prod in db.Products.Where(prod => prod.Person_ID == prsn.Person_ID).DefaultIfEmpty()
select new { Person = prsn.NAME, Company = co.NAME, Product = prod.NAME })
This uses a mix of linq query syntax and lambda syntax to what (I believe is) the best result. There's no copious re-aliasing of identifiers, and it's the most concise way to do this that I've seen.

Resources