How to write multiple outer left join in linq? - 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

Related

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?

Doing a Left outer join in a linq query

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()

Multiple column join in linq

I want to convert this sql query to linq
SELECT Students.StdId, Mark.Value
FROM Departments INNER JOIN
Mark ON Departments.DepId = Mark.DepId INNER JOIN
Students ON Departments.DepId = Students.DepId AND Mark.StdId = Students.StdId
I did this, but it's wont working
from s in Students
join d in Departments on s.DepId equals d.DepId
join m in Marks on new {s.StdId, d.DepId} equals new {m.StdId, m.DepId}
select new{
SId=s.StdId,
Value=m.Value
}
Lets try with
from s in Students
join d in Departments on s.DepId equals d.DepId
join m in Marks
on new {StdId = s.StdId, DepId = d.DepId} equals new {StdId = m.StdId, DepId= m.DepId}
select new{
SId=s.StdId,
Value=m.Value
}
How about
from s in Students
join m in Marks on s.StdId equals m.StdId
join d in Departments on m.DepId equals d.DepId
select new { s.StdId, m.Value };

Linq left outer join and group by issue

Hi All my following query returns results like this:
lstView.DataSource = (from h in context.HolidayMains
join hd in context.HolidayDetails on h.Id equals hd.HolidayMainId into hd2
from hd in hd2.DefaultIfEmpty()
join e in context.Employees on h.CreatedBy equals e.Id into e2
from e in e2.DefaultIfEmpty()
join o in context.OfficeLocations on hd.OfficeLocation equals o.Id into o2
from o in o2.DefaultIfEmpty()
select new
{
h.HolidayTitle,
h.Date,
OfficeLocation = o.Name,
CreatedBy = e.Name,
h.Id
}).ToList();
But I need result like this :
How it can be done?

left outer join problem

I need to convert some SQL statement to LINQ. How convert LEFT OUTER JOIN to equivalent LINQ statement?
You need to use the DefaultIfEmpty operator. The below code should result in a left outer join.
var q = from c in customers
join o in orders on c.Key equals o.Key into g
from o in g.DefaultIfEmpty()
select new {Name = c.Name, OrderNumber = o == null ? "(no orders)" : o.OrderNumber};
Credit to: http://www.hookedonlinq.com/OuterJoinSample.ashx

Resources