Doing a Left outer join in a linq query - linq

I have the query below that works in sqllite with a left outer join
select * from customer cu
inner join contract cnt on cu.customerId = cnt.customerid
inner join address addy on cu.addressid = addy.addressId
inner join csrAssoc cassc on cu.customerid = cassc.customerId
left outer join CustomerServiceRepresentative csrr on cassc.csrid = csrr.customerservicerepresentativeId
inner join customerServiceManager csmm on cassc.csmid = csmm.customerservicemanagerId
where cu.customernumber = '22222234'
I want to be able to apply a left outer join on this line in the linq query below
join csrr in objCsrCustServRep.AsEnumerable() on cassc.CsrId equals
csrr.CustomerServiceRepresentativeId
VisitRepData = (from cu in objCustomer.AsEnumerable()
join cnt in objContract.AsEnumerable() on cu.customerId equals cnt.customerId
join addy in objAddress.AsEnumerable() on cu.addressId equals addy.addressId
join cassc in objCsrAssoc.AsEnumerable() on cu.customerId equals cassc.CustomerId
join csrr in objCsrCustServRep.AsEnumerable() on cassc.CsrId equals
csrr.CustomerServiceRepresentativeId
join csmm in objCustServMan on cassc.CsmId.ToString() equals csmm.customerServiceManagerId
where cu.CustomerNumber == (customernbr)
How can I do a left outer join in a linq query?
Here is my comment after adjusting and running the code. The other section is also added. All am getting is object is not set to an instance of an object.
var VisitRepData = from cu in objCustomer.AsEnumerable()
join cnt in objContract.AsEnumerable() on cu.customerId equals cnt.customerId
join addy in objAddress.AsEnumerable() on cu.addressId equals addy.addressId
join cassc in objCsrAssoc.AsEnumerable() on cu.customerId equals cassc.CustomerId
join csrr in objCsrCustServRep.AsEnumerable() on cassc.CsrId equals
csrr.CustomerServiceRepresentativeId into temp
from tempItem in temp.DefaultIfEmpty()
join csmm in objCustServMan on cassc.CsmId.ToString() equals csmm.customerServiceManagerId
where cu.CustomerNumber == (customernbr)
select new
{
cu.customerId,
cu.CustomerNumber,
cu.customerName,
cu.dateActive,
cnt.contractExpirationDate,
addy.street,
addy.street2,
addy.city,
addy.state,
addy.zipcode,
cu.EMail,
cu.phoneNo,
cu.faxNumber,
csmm.customerServiceManagerName,
tempItem.CustomerServiceRepresentativeName,
};
foreach (var item in VisitRepData)
{
var one = item.customerId;
var two = item.CustomerNumber;
}

Per documentation:
A left outer join is a join in which each element of the first collection is returned, regardless of whether it has any correlated elements in the second collection. You can use LINQ to perform a left outer join by calling the DefaultIfEmpty method on the results of a group join
(emphasis mine)
Based on MSDN link above, and if I understood your requirements correctly, query should look like this:
VisitRepData = from cu in objCustomer.AsEnumerable()
join cnt in objContract.AsEnumerable() on cu.customerId equals cnt.customerId
join addy in objAddress.AsEnumerable() on cu.addressId equals addy.addressId
join cassc in objCsrAssoc.AsEnumerable() on cu.customerId equals cassc.CustomerId
join csrr in objCsrCustServRep.AsEnumerable() on cassc.CsrId equals
csrr.CustomerServiceRepresentativeId into temp
from tempItem in temp.DefaultIfEmpty()
join csmm in objCustServMan on cassc.CsmId.ToString() equals csmm.customerServiceManagerId
where cu.CustomerNumber == (customernbr)
Specifically, the left outer join is performed with this code:
join csrr in objCsrCustServRep.AsEnumerable()
on cassc.CsrId equals csrr.CustomerServiceRepresentativeId
into temp
from tempItem in temp.DefaultIfEmpty()

Related

How can I convert this query from SQL to linq

Can anyone help me converting this SQL query to linq:
select fi.CreatedOn, fi.Id
from Branch br
inner join Asset a on br.Id = a.BranchId
inner join Inspection i on i.AssetId = a.Id
inner join FormInstance fi on i.FormInstanceId = fi.Id
inner join [User] u on u.HomeBranchId = br.Id
where br.Id like 'xxx'
group by fi.CreatedOn, fi.Id
order by fi.CreatedOn desc
This is what I got so far, but I don't understand how to do the group by part
from fi in model.FormInstance
join ins in model.Inspections on fi.Id equals ins.FormInstanceId
join a in model.Assets on ins.AssetId equals a.Id
join br in model.Branches on a.BranchId equals br.Id
join usr in model.Users on br.Id equals usr.HomeBranchId
where br.Id == gBranchId
group fi by fi.Id
You have missed defining right grouping key.
query =
from fi in model.FormInstance
join ins in model.Inspections on fi.Id equals ins.FormInstanceId
join a in model.Assets on ins.AssetId equals a.Id
join br in model.Branches on a.BranchId equals br.Id
join usr in model.Users on br.Id equals usr.HomeBranchId
where br.Id == gBranchId
group fi by new { fi.CreatedOn, fi.Id } into g
select g.Key;
query = query.OrderByDescending(x => x.CreatedOn);

LINQ - Subquery or LEFT OUTER JOIN?

I am trying to optimize my LINQ query performance, and I've noticed a lot of LEFT OUTER JOINs being generated. I know that in SQL, there are some cases in which a single row subquery works better than the equivalent LEFT OUTER JOIN.
For example:
Query 1:
select f.FacilityName, p.Id PatientId, u.DOB, (select u2.NameComputed from adm.Staffs s inner join dbo.AspNetUsers u2 on s.UserId = u2.Id where s.Id = p.StaffId) AssignedTo
from ptn.Patients p
inner join dbo.AspNetUsers u on p.UserId = u.Id
inner join hco.Hcos f on p.HcoId = f.Id
where p.IsRemoved = 0
Query 2:
select f.FacilityName, p.Id PatientId, u.DOB, u2.NameComputed
from ptn.Patients p
inner join dbo.AspNetUsers u on p.UserId = u.Id
inner join hco.Hcos f on p.HcoId = f.Id
left outer join adm.Staffs s on p.StaffId = s.Id
left outer join dbo.AspNetUsers u2 on s.UserId = u2.Id
where p.IsRemoved = 0
Query 1 takes less than a second. Query 2 takes about 45 seconds. If I wanted to make sure LINQ is structured in such a way as to take advantage of this in some cases, how would I go about doing that? That is, is there a way to write a LINQ statement that produces a subquery instead of a LEFT OUTER JOIN?

LEFT OUTER JOIN WHEN IT HAS MULTIPLE TABLE SELECT QUERY

Currently I have joined two tables using inner join , like following
SELECT A.*,B.*
FROM A,B
WHERE A.COLUMN_A = B.COLUMN_B
now I want to join Left outer join to above results , lets say I want to join Table C
So I did like following
SELECT A.*,B.*
FROM A,B
LEFT OUTER JOIN C ON B.COLUMN_X = C.COLUMN_X
WHERE A.COLUMN_A = B.COLUMN_B
this is executing without errors in SQL navigator, But in this result I cannot see any output.
anything wrong in this query , please advise
Change it to have proper join syntax like
SELECT A.*,B.*
FROM A
INNER JOIN B ON A.COLUMN_A = B.COLUMN_B
LEFT OUTER JOIN C ON B.COLUMN_X = C.COLUMN_X;
Better change all to outer join
SELECT A.*,B.*
FROM A
LEFT JOIN B ON A.COLUMN_A = B.COLUMN_B
LEFT OUTER JOIN C ON B.COLUMN_X = C.COLUMN_X;
Use this
SELECT A.*,B.*,C.*
FROM A
INNER JOIN B
ON A.COLUMN_A = B.COLUMN_B
LEFT OUTER JOIN C
ON B.COLUMN_X = C.COLUMN_X
If you absolutely have to use legacy syntax, then use this. But I won't recommend it.
SELECT A.*,B.*,C.*
FROM A,B,C
where A.COLUMN_A = B.COLUMN_B
AND
B.COLUMN_X = C.COLUMN_X (+)

Left join to a SET using linq

In SQL, I would commonly inner join two or more tables to create a set and then left join to that set:
select *
from TableA
left outer join
TableB
inner join TableC on TableB.Id = TableC.TableBId
on TableA.Id = TableB.TableAId
What is the Linq equivalent of this? I'm using EF Code First.
Like this:
var result = from a in TableA
join b in TableB on a.Id equals b.TableAId into ab
from b in ab.DefaultIfEmpty()
join c in TableC on b.Id equals c.TableBId
select a;
I was able to achieve this by breaking it into two statements. First, make your inner join set, then left join to that set.
var bc = from b in TableB
join c in TableC on b.Id equals c.TableBId
select new { B = b, C = c };
var result = from a in TableA
from bcRow in bc.Where(row => a.Id equals row.B.TableAId).DefaultIfEmpty()
select new { A = a, B = bcRow.B, C = bcRow.C };

How to write multiple outer left join in linq?

I am trying to outer join multiple tables. Here I have pasted my code what I am trying to do.
from o in entities.O
join p in entities.P on o.PID equals p.ID
join dC in entities.C on o.DCID equals dC.ID
join hC in entities.C on o.HCID equals hC.ID
join e in entities.E on pat.AN equals e.UID
join oT in entities.OT on o.OT equals oT.ID
join plt in entities.PLT on p.LT equals plt.ID
join puO in entities.PUO on o.PUTId equals puO.ID into pots
from x in pots.DefaultIfEmpty()
join op in entities.OP on o.OPID equals op.ID
join prt in entities.PatientRelationshipTypes on pat.PRTId equals prt.ID
join secPRT in entities.PRT on pat.SRTId equals secPRT.ID
join patDiagCode in entities.PDiagnosisCodes on pat.ID equals patDiagCode.PID
//from y in pdc.DefaultIfEmpty()
join diagCode in entities.DCodes on patDiagCode.CodeID equals diagCode.ID into dc
from z in dc.DefaultIfEmpty()
where o.ID == orderId
//from x in pots.DefaultIfEmpty()
//from y in pdc.DefaultIfEmpty()
...
...
How do I write correct syntax for multiple outer join in Linq?
Thanks in advance

Resources