convert trans-sql to LINQ LEFT JOIN and Where Clause - c#

How would you convert this trans-sql to LINQ?
I've tried it with the DefaultIfEmpty() but it seems to not be working for me.
Any help is appreciated.
SELECT s.Status
FROM EducationModule M
LEFT JOIN EducationModuleStatus S ON M.CourseID = S.CourseID
AND M.ModuleID = S.ModuleID
AND S.StudentID = '1506'
WHERE M.courseid = 2
Thanks in advance.

Joining on multiple columns in Linq to SQL is a little different.
You have to take advantage of anonymous types and compose a type for the multiple columns you wish to compare against, and under the sheet this will generate the type of join you are looking for.
var abcd = from tl in db.EducationModule
join s in db.EducationModuleStatus
on new { t1.CourseID, t1.ModuleID } equals new {s.CourseID, s.ModuleID}
into tl_s
where tl.CourseID == 2 AND s.StudentID == '1506'
from s in tl_s.DefaultIfEmpty()
select new
{
Status = s.Status
};

Related

Left join with where clause in linq

I am trying to do a left join with a where clause in linq.
I have leadsQuery table with 2500 rows. I want to join the LeadCons table into it. For a lead there can be multiple entries in the LeadCons table, hence I want to join only when the Status match. Else I want the fields to be NULL.
var data = from lead in leadsQuery
join lcs in context.LeadCons on lead.ID equals lcs.LeadId into leadsWithCons
from lcs in leadsWithCons.DefaultIfEmpty()
where lead.Status == lcs.Status
select new
{
LeadId = lead.ID,
Source = lead.Source.ToString(),
};
This query gives me ~1500 rows and leadsQuery has 2500. What am I doing wrong here?
A late answer, hoping it is still helpful:
First, you aren't selecting any values from LeadCons, so what is the purpose of a join?
I shall assume maybe you want to extend your select, so let us say you want to select the property foo, so my next question: Why do you need a left join in your case? You can simply do a select:
var data = from lead in leadsQuery
select new
{
Foo = context.LeadCons.Where(lcs => lead.Status == lcs.Status).SingleOrDefault().foo
LeadId = lead.ID,
Source = lead.Source.ToString(),
};
This way you have the same number of items and for each item the desired foo value.
Have you tried just changing the your join to a join with multiple conditions, and then removing the where 'status equal status'
from lead in leadsQuery
join lcs in context.LeadCons on new {
p1 = lead.ID,
p2 = lead.Status
}
equals
new {
p1 = lcs.LeadId,
p2 = lcs.Status
}
you can have a look at this nice article:
https://smehrozalam.wordpress.com/2010/04/13/linq-how-to-write-queries-with-complex-join-conditions/

LINQ Select newest records that have distinct ForeignKeyId column

I have the following SQL query:
SELECT
table1.Id AS EinAusgangId,
table1.Ausgabedatum,
table1.Rueckgabedatum,
table1.WerkzeugId,
cpmWerkzeug.Name
FROM cpmEinAusgang AS table1
INNER JOIN cpmWerkzeug ON table1.WerkzeugId = cpmWerkzeug.Id
WHERE table1.Id = (SELECT MAX(Id) AS Expr1
FROM dbo.cpmEinAusgang
WHERE table1.WerkzeugId = WerkzeugId)
My aim is to convert the whole query into a LINQ statement for further use in a .Net Application. I already converted joined tables to LINQ but is it also possible to use a select in the where clause?
This is what I got so far, which gives me almost the same result as the SQL statement above, but has major errors when the table cpmEinAusgang contains more then one record for one cpmWerkzeug
using (var dbContext = new cpmEntities())
{
var werkzeuge = from w in dbContext.cpmWerkzeug
join e in dbContext.cpmEinAusgang
on w.Id equals e.WerkzeugId
where e.Rueckgabedatum == null
orderby w.Name
select w;
return werkzeuge.ToList();
}
Has anyone an idea how to achieve the above sql in linq?
Thanks for your help. :)
EDIT:solved (see below)
var werkzeugeImUmlauf = from w in dbContext.cpmWerkzeug
join e in dbContext.cpmEinAusgang
on w.Id equals e.WerkzeugId
where e.Id == dbContext.cpmEinAusgang.Where(x => x.WerkzeugId == e.WerkzeugId).Max(x => x.Id) select w;
This is the final solution. As mentioned by Mittal in his answer, it is possible to write a sub-query in LINQ.
Yes, you can write Sub Query in LINQ as well.
var werkzeuge = from w in dbContext.cpmWerkzeug
join e in dbContext.cpmEinAusgang
on w.Id equals e.WerkzeugId
where w.id = (dbContext.cpmEinAusgang.Max(x => x.id)) AND w.WerkzeugId = WerkzeugId

Combining Querys

I am using Linq to Sql to get two lists than take Union with another list. They are working fine. But I am wondering if it can be done in one Query or two instead of three that I have.
Querys are
var l = (from t in T_list1
where t.Date == DateTime.Today
select new
{
oldDate=t.OldDate,
Name=t.name,
Email=t.EmailAddress,
list2TableId=t.l2Id,
CustomerId=t.customerId
});
var l2=(from d in T_list2
from e in l1
where d.Id == e.list2TableId
select new
{
Date=d.oldDate,
CName=d.Name,
Experience=e.experience,
});
list2.Dump();
var l3 = list2.Union(list3).ToList();
I was looking at this post but didnt work. Combining 2 Linq queries into 1
Thanks for your input.
You could do a join instead of the 2 queries:
var l = (from t in T_list1
join d in T_list2 on t.l2Id equals d.Id
where t.Date == DateTime.Today
select new
{
oldDate=t.OldDate,
Name=t.name,
Email=t.EmailAddress,
list2TableId=t.l2Id,
CustomerId=t.customerId
Date=d.oldDate,
CName=d.Name
Experience=e.experience,
});
I haven't tested the query but it should show you the rough idea.
Have a look at JOINs in SQL & Linq to get more information.

Use LINQ to Join on Multiple Fields

How would I do this in LINQ?
SQL
Where tblAccounts.AccountCode = tblAccountAssociations.ChildCode
And tblAccountAssociations.AssociationType = "DS"
Here is my attempt. The problem seems to be with "assoc.AssociationType == "DS". Is it part of the join or the Where clause?
var customers =
from customer in context.tblAccounts
join assoc in context.tblAccountAssociations on customer.AccountCode equals assoc.ChildCode
where customer.AccountType == "S" and assoc.AssociationType == "DS"
orderby customer.AccountType
select new { Customer = customer, Assoc = assoc };
Thanks in advance
According to MSDN (http://msdn.microsoft.com/en-us/library/bb311043.aspx), you use "&&", not "and", to specify multiple conditions in the "where" clause.
var customers =
from customer in context.tblAccounts
join assoc in context.tblAccountAssociations on customer.AccountCode equals assoc.ChildCode
where customer.AccountType == "S" **&&** assoc.AssociationType == "DS"
orderby customer.AccountType
select new { Customer = customer, Assoc = assoc };
Yes, "and" should be "&&", but the answer to your question is that in Linq the predicate assoc.AssociationType == "DS is not part of the join.
In SQL you could make it part of a join statement
...
FROM tblAccounts c
INNER JOIN tblAccountAssociations a ON
c.AccountCode = a.ChildCode AND a.AssociationType == "DS"
...
but in Linq statments you just add it as a predicate, the way you did (apart from the "and" issue).
In SQL, in terms of execution plan (performance), it does not matter whether you add it to the JOIN phrase or put it into a separate WHERE condition.

linq - how combine conditions in a join statement

im working with xml and linq.
I have 2 xml files both contain "ID" and "LANGUAGE"
I want to do a join based on where the both the ID and LANGUAGE are equal in both files
I have something like this:
var data=
from details in h_details.Descendants("ROW")
join inst in instance.XPathSelectElements("//Row")
on details.Element("ID").Value
equals inst.XPathSelectElement("Field[#Name=\'h_id\']").Value
and on details.Element("LANGUAGE").Value
equals inst.XPathSelectElement("Field[#Name=\'h_lang\']").Value
basically the "and" statement wont work, so how do i join based on 2 conditions?
Anonymous types to the rescue.
var data=
from details in h_details.Descendants("ROW")
join inst in instance.XPathSelectElements("//Row")
on new {
x = details.Element("ID").Value,
y = details.Element("LANGUAGE").Value
} equals new {
x = inst.XPathSelectElement("Field[#Name=\'h_id\']").Value,
y = inst.XPathSelectElement("Field[#Name=\'h_lang\']").Value
}
select ... ;
try union to get the both lists and join them

Categories

Resources