how to use left join in entity framework query? [duplicate] - c#

This question already has answers here:
LINQ - Left Join, Group By, and Count
(5 answers)
Closed 9 years ago.
I am working with entity framework 4.5. I have to convert an SQL query to entity query:
SELECT Customer.CustCode, Invoice.InvoiceId, Invoice.BatchNumber, Invoice.InvoiceDate, Invoice.AdjustFlag, Invoice.InvoiceAmount,
Invoice.InvoiceNote, Invoice.AmountPaid, Customer.BillingContact, Customer.BillingCompany, Customer.BillingStreet1,
Customer.BillingStreet2, Customer.BillingCity, Customer.BillingState, Customer.BillingZip, [Order].PickupDate, [Order].OrderNumber,
[Order].OrderTotal, [Order].ProNumber, [Order].PickupCompany, [Order].PickupCity, [Order].PickUpState, [Order].Dcompany,
[Order].Dcity, [Order].Dstate, CONVERT(varchar(5), DeliverInTime, 114) AS DelInTime, [Order].PiecesWeight1, [Order].BaseRATE,
[Order].POD, [Order].Requester, [Order].Po1, [Order].Po2, AccessorialCharge.Description,
OrderDriverExtraCharge.AccessorialChargeDesc, OrderDriverExtraCharge.AccessorialChargeAmount, [Order].NormalDiscount,
- 1 * [Order].DISCAmount AS DISCAmount
FROM (((Invoice INNER JOIN
[Order] ON Invoice.InvoiceId = [Order].InvoiceId) INNER JOIN
Customer ON Invoice.CustID = Customer.CustID) LEFT JOIN
OrderDriverExtraCharge ON [Order].OrderNumberId = OrderDriverExtraCharge.OrderNumberId) LEFT JOIN
AccessorialCharge ON OrderDriverExtraCharge.AccessorialChargeId = AccessorialCharge.AccessorialChargeId
where Invoice.InvoiceId = '1117782'
If I change OrderDriverExtraCharge.OrderNumberId) LEFT JOIN to OrderDriverExtraCharge.OrderNumberId) JOIN (simple join) or inner join it's not showing the right result.
I have tried this:
from I in db.Invoices
join O in db.Orders on I.InvoiceId equals O.InvoiceId
join C in db.Customers on I.CustId equals C.CustId
join OD in db.OrderDriverExtraCharges on O.OrderNumberId equals OD.OrderNumberId
join AC in db.AccessorialCharges on OD.AccessorialChargeId equals AC.AccessorialChargeId
where I.InvoiceId == invoice.InvoiceId
select new PrintInvoiceViewModel()
But it is not showing the required results. Please help me, I will mark your answer if it worked for me. Thank you.

You can do this:
from I in db.Invoices
join O in db.Orders on I.InvoiceId equals O.InvoiceId
join C in db.Customers on I.CustId equals C.CustId
from OD in db.OrderDriverExtraCharges
.Where(w=>w.OrderNumberId==O.OrderNumberId).DefaultIfEmpty()
from AC in db.AccessorialCharges
.Where(w=>w.AccessorialChargeId==OD.AccessorialChargeId).DefaultIfEmpty()
where I.InvoiceId == invoice.InvoiceId
select new PrintInvoiceViewModel()

Your should use DefaultIfEmpty method, which returns the elements of an IEnumerable<T>, or a default valued singleton collection if the sequence is empty:
from I in db.Invoices
join O in db.Orders on I.InvoiceId equals O.InvoiceId
join C in db.Customers on I.CustId equals C.CustId
join OD in db.OrderDriverExtraCharges on O.OrderNumberId equals OD.OrderNumberId into ODs
from OD in ODs.DefaultIfEmpty()
join AC in db.AccessorialCharges on OD.AccessorialChargeId equals AC.AccessorialChargeId into ACs
from AS in ACs.DefaultIfEmpty()
where I.InvoiceId == invoice.InvoiceId
select new PrintInvoiceViewModel()

Related

Multiple JOIN in Linq-to-SQL

I'm trying to do the following query in linq-to-sql (joining 3 different tables):
select * from tbl_round r
inner join tbl_election e on r.fk_election_id = e.election_id
inner join tbl_meeting m on m.meeting_id = e.fk_meeting_id
Here is what I have so far but not correct:
from round in db.tbl_rounds
join meeting in db.tbl_meetings on election.fk_meeting_id equals meeting.meeting_id
join election in db.tbl_elections on round.fk_election_id equals election.election_id
select round;
The error I'm getting is that the name 'election' does not exist in the current context.
You will have to re-order the join statement probably like
from round in db.tbl_rounds
join election in db.tbl_elections on round.fk_election_id equals election.election_id
join meeting in db.tbl_meetings on election.fk_meeting_id equals meeting.meeting_id
select round;
Because you have "election" used before it is declared.
from round in db.tbl_rounds
join meeting in db.tbl_meetings on -->election<--.fk_meeting_id equals meeting.meeting_id
join -->election<-- in db.tbl_elections on round.fk_election_id equals election.election_id
select round;
In this case, you will need to change order in your query.
Query should look like this:
from round in db.tbl_rounds
join election in db.tbl_elections on round.fk_election_id equals election.election_id
join meeting in db.tbl_meetings on election.fk_meeting_id equals meeting.meeting_id
select round;

SQL Outer Join in LINQ

I've got the following LINQ Query
from s in db.tblSave
join a in db.tblAssessment on s.AssessmentID equals a.Id
join staff in db.tblStaff on s.StaffID equals staff.Id
join student in db.tblStudent on s.StudentID equals student.Id
join signed in db.tblSaveSigned on s.Id equals signed.SaveID
select new
{
SaveID = s.Id,
StaffName = staff.StaffName,
AssessmentName = a.AssessmentName,
StudentName= student.StudentName,
CreatedDate = s.CreatedDate,
SignedDate = signed.SignedDate}
tblSaveSigned may not have a record against tblSave which is excluding some tblSave records. How do I include all tblSave records in my results? It's an outer join in SQL but not sure how to do it in LINQ.
Thanks in advance.
Is there an SQL to LINQ tool?
Below is the correct LINQ Query for put FULL OUTER JOIN on tblSave for tblSaveSigned. Thanks for NetMage for pointing me in the right direction.
from s in db.tblSave
join a in db.tblAssessment on s.AssessmentID equals a.Id
join staff in db.tblStaff on s.StaffID equals staff.Id
join student in db.tblStudent on s.StudentID equals student.Id
join signed in db.tblSaveSigned on s.Id equals signed.SaveID into signedj
from signed in signedj.DefaultIfEmpty()
select new
{
SaveID = s.Id,
StaffName = staff.StaffName,
AssessmentName = a.AssessmentName,
StudentName= student.StudentName,
CreatedDate = s.CreatedDate,
SignedDate = signed.SignedDate}

Transform SQL query to Linq left join clause incorrect

I'm trying to select the MatchingObjects that doesn't exist in the Unlock table , I have this SQL query as following:
select a.* from MatchingObjects a
left join Unlocks b
on a.ObjectCategoryId = b.ObjectCategoryId
left join Members c
on b.StudentId = c.Id
and b.StudentId = #studentId
where b.ObjectCategoryId is null
and c.id is null
order by a.ObjectCategoryId
And a LINQ query
var query = (from d in db.ObjectCategories
join a in db.MatchingObjects on d.Id equals a.ObjectCategoryId into grp3
join b in db.Unlocks
on d.Id equals b.ObjectCategoryId into grp1
from m in grp1.DefaultIfEmpty()
join c in db.Members
on m.StudentId equals c.Id into grp2
from n in grp2.DefaultIfEmpty()
where m.ObjectCategoryId == null
&& n.Id == null
orderby d.Id).AsEnumerable()
;
However, the LINQ query is not showing the same result as that I want like in the SQL query. Could you guys tell me what I should change in my LINQ Query?
This is the model:
Better you can use below tools:
An SQL-> LINQ converter..
http://www.sqltolinq.com
http://www.linqpad.net/
try this one
var query = from m in db.MatchingObjects.Where(w => w.ObjectCategoryId == null)
join u in db.Unlocks.Where(w => w.studentId == #studentId)
on m.ObjectCategoryId equals u.ObjectCategoryId into joinedU
from ju in joinedU.DefaultIfEmpty()
join m in db.Members.Where(w => w.id == null)
on ju.StudentId equals m.Id into joinedM
from jm in joinedM.DefaultIfEmpty()
select m;
But your request is a bit Strange. You make the join by ObjectCategoryId and in the Where clause you put ObjectCategoryId == null!!!
sorry guys, the Sql and the LINQ query was a bit different in table selection. I'm sorry about that because I was trying different Linq while posting the question, but The main problem is at the join clause
(from d in db.ObjectCategories
join a in db.MatchingObjects
on d.Id equals a.ObjectCategoryId into grp3
join b in db.Unlocks
on d.Id equals b.ObjectCategoryId into grp1
from m in grp1.DefaultIfEmpty()
join c in db.Members
on m.StudentId equals studentId into grp2
from n in grp2.DefaultIfEmpty()
where m.ObjectCategoryId == null
where n.Id == null
orderby d.Id).AsEnumerable()
/* this is the correct one */
join c in db.Members
on m.StudentId equals studentId into grp2
/* the below was the original incorrect join clause*/
join c in db.Members
on m.StudentId equals c.Id into grp2

How can I rewrite the following SQL query into LINQ query?

I want to rewrite the following SQL query in LINQ. But my problem is that I don't know how to write an AND (&&) operator with a LINQ LEFT JOIN (look at my second left join).
SELECT emp.EmployeeId,
dsg.Name,
pob.CompanyContribution,
pob.EmployeeContribution,
pob.OpeningIncome
FROM HrmEmployees AS emp
LEFT JOIN HrmDesignations AS dsg ON emp.HrmDesignationId=dsg.Id
LEFT JOIN PfmOpeningBalance AS pob ON emp.Id=pob.HrmEmployeeId AND pob.CmnCalendarYearId=2
WHERE emp.Id=6
I tried the following one. But getting compile error-
from emp in dbContext.EmployeeList
join dsg in dbContext.hrmDesig on emp.HrmDesignationId equals dsg.Id into DSGLeftJoin
from dsglj in DSGLeftJoin.DefaultIfEmpty()
join pob in dbContext.PfOpeningBalances on emp.Id equals pob.HrmEmployeeId into POBLeftJoin
from poblj in POBLeftJoin.DefaultIfEmpty() && poblj.CmnCalendarYearId == clndrId
where emp.Id==empId
select new
{
empIdr = emp.Id,
EmployeeId = emp.EmployeeId,
EmployeeName = emp.Name,
Designation = dsglj.Name,
OpeningIncome = poblj.OpeningIncome,
EmployeeContribution = poblj.EmployeeContribution,
CompanyContribution = poblj.CompanyContribution
}
Try this.
(from emp in HrmEmployees
join dsg in HrmDesignations
on emp.HrmDesignationId equals dsg.Id
join pob in PfmOpeningBalance
on emp.Id equals pob.HrmEmployeeId AND pob.CmnCalendarYearId equals 2
into eGroup
from emps in eGroup.DefaultIfEmpty()
emp.Id=6
select new
{
EmployeeId =emp.EmployeeId,
Name=dsg.Name,
CompanyContribution=pob.CompanyContribution,
EmployeeContribution=pob.EmployeeContribution,
OpeningIncome=pob.OpeningIncome
}).ToList();
OK you can try like this;
from emp in dbContext.EmployeeList
join dsg in dbContext.hrmDesig on emp.HrmDesignationId=dsg.Id
join pob in dbContext.PfOpeningBalanceson new {emp.Id, jp=pob.CmnCalendarYearId} equals new {pob.HrmEmployeeId, jp=2}
where emp.Id=6
select new {emp.EmployeeId,
dsg.Name,
pob.CompanyContribution,
pob.EmployeeContribution,
pob.OpeningIncome};
Or like this;
from emp in dbContext.EmployeeList.Where(e=>e.Id.Equals(6))
join dsg in dbContext.hrmDesig on emp.HrmDesignationId=dsg.Id
join pob in dbContext.PfOpeningBalanceson.Where(x=>x.CmnCalendarYearId.Equals(2)) on emp.Id equals pob.HrmEmployeeId
select new {emp.EmployeeId,
dsg.Name,
pob.CompanyContribution,
pob.EmployeeContribution,
pob.OpeningIncome};

multiple left joins with Linq

I'm struggling with a Linq query involving left joins. Here is the SQL I'm trying to convert:
SELECT EmailStats.EmailAddress, EmailVoting.DateAdded, EmailVoting.ResponseText,
EmailStats.DateSent, EmailAlerts.Name, UserDetails.EmployeeNumber
FROM EmailAlerts
INNER JOIN EmailStats
ON EmailAlerts.EmailAlertID = EmailStats.EmailAlertID
INNER JOIN UserDetails
ON EmailStats.UserId = UserDetails.UserId
LEFT OUTER JOIN EmailVoting
ON EmailAlerts.EmailAlertID = EmailVoting.EmailAlertID
AND EmailVoting.UserId = EmailStats.UserId
Where EmailAlerts.EmailAlertID = 43 AND EmailStats.IsTestSend = 0
The SQL is returning the correct data with the EmailVoting fields null if the rows don't exist. Below is the LINQ I currently have:
from ea in db.EmailAlerts
join es in db.EmailStats on ea.EmailAlertID equals es.EmailAlertID
join ud in db.UserDetails on es.UserId equals ud.UserId
join ev in db.EmailVoting on ea.EmailAlertID equals ev.EmailAlertID into vm
from v in vm.DefaultIfEmpty()
join ev in db.EmailVoting on es.UserId equals ev.UserId into udItems
from u in udItems.DefaultIfEmpty()
where v.EmailAlertID == emailAlertID
What I thought was the same in LINQ, isn't displaying correctly and is in fact displaying an entry with a different EmailAlertID. Anyone see where I might be going wrong?
Thanks
Try this:
from ea in db.EmailAlerts
join es in db.EmailStats on ea.EmailAlertID equals es.EmailAlertID
join ud in db.UserDetails on es.UserId equals ud.UserId
join ev in db.EmailVoting on new {ev.EmailAlertID, ev.UserId} equals new {ea.EmailAlertID, es.UserId} into vm
from v in vm.DefaultIfEmpty()
where v.EmailAlertID == emailAlertID

Categories

Resources