The best way to join in Linq - c#

I was working with the first method below, but then I found the second and want to know the difference and which is best.
What is the difference between:
from a in this.dataContext.reglements
join b in this.dataContext.Clients on a.Id_client equals b.Id
select...
and
from a in this.dataContext.reglements
from b in this.dataContext.Clients
where a.Id_client == b.Id
select...

I created a test case to test out the difference, and in your scenerio it turns out they are the same.
My test example used AdventureWorks but basically there is an association between
Products->CategoryId->Categories
var q = (
from p in Products
from c in Categories
where p.CategoryID==c.CategoryID
select p
);
q.ToList();
Produces this SQL:
SELECT [t0].[ProductID], [t0].[ProductName], [t0].[CategoryID]
FROM [Products] AS [t0], [Categories] AS [t1]
WHERE [t0].[CategoryID] = ([t1].[CategoryID])
var q2 = (
from p in Products
join c in Categories
on p.CategoryID equals c.CategoryID
select p);
q2.ToList();
Produces this sql:
SELECT [t0].[ProductID], [t0].[ProductName], [t0].[CategoryID]
FROM [Products] AS [t0]
INNER JOIN [Categories] AS [t1] ON [t0].[CategoryID] = ([t1].[CategoryID])

The difference between these two syntaxes will be in the way they are translated into SQL. You can trace Entity Framework or LINQ to SQL to determine the SQL:
LINQ to SQL: http://www.reflectionit.nl/Blog/PermaLinkcba15978-c792-44c9-aff2-26dbcc0da81e.aspx
Check the resulting SQL to determine if there are any differences that could affect performance.

Related

LINQ to SQL, multiple table join, generated SQL missing 2nd INNER JOIN

Can anyone tell me why the generated SQL does not contain a 2nd INNER JOIN? It seems to have been replaced with a NULL check in the WHERE clause? I'm not clear on why the 2nd INNER JOIN is not in the generated SQL.
C# code:
var cycleList = from o in entities.Orders
join c in entities.Cycles on o.Id equals c.OrderId
join calendar in entities.Calendars on c.CalendarId equals calendar.Id
where o.UnitId == unitId && o.CompanyId == companyId
select c.Id;
Generated SQL:
SELECT
[Extent2].[Id] AS [Id]
FROM [dbo].[Orders] AS [Extent1]
INNER JOIN [dbo].[Cycles] AS [Extent2] ON [Extent1].[Id] = [Extent2].[OrderId]
WHERE ([Extent2].[CalendarId] IS NOT NULL) AND ( CAST( [Extent1].[UnitId] AS int) = #p__linq__0) AND ( CAST( [Extent1].[CompanyId] AS int) = #p__linq__1)
It looks like the query generator is optimizing your query.
Since you are not selecting (or using in your where clause) any fields from the Calendars table in your query, only one join is done between the Orders table and the Cycles table. It's likely faster to check for the non-NULL foreign key than it is to join on a table from which no fields will be used.

Multiple table join with multiple table where clause

I have a query that's something like this.
Select a.*
from table1 a
inner join table2 b on a.field1 = b.field1
inner join table3 c on b.field2 = c.field2
where b.field4 = beta and c.field5 = gamma.
On LINQ, I tried to do that this way:
var query = (from a in table1
join b in table2 on a["field1"] equals b["field1"]
join c in table3 on b["field2"] equals c["field2"]
where (b["field4"] == beta && c["field5"] == gamma)
select a).ToList();
But for some reason, when I try to do this I get an error that says that the entity "table2" doesn't have the field Name = "field5", as though as the where clause was all about the last joined table and the other ones were unaccessible. Furthermore, the compiler doesn't seem to notice neither, because it lets me write c["field5"] == gamma with no warning.
Any ideas? Am I writing this wrong?
Thanks
See these links:
How to: Perform Inner Joins (C# Programming Guide)
What is the syntax for an inner join in linq to sql?
Why you don't create View in database, and Select your data from View in LINQ?

linq-to-sql joins with multiple from clauses syntax vs. traditional join syntax

What the difference between writing a join using 2 from clauses and a where like this:
var SomeQuery = from a in MyDC.Table1
from b in MyDC.Table2
where a.SomeCol1 == SomeParameter && a.SomeCol2 === b.SomeCol1
and writing a join using the join operator.
This is for a join on 2 tables but of course, sometimes, we need to join even more tables and we need to combine other from clauses with where if we choose the syntax above.
I know both syntax queries return the same data but I was wondering if there's a performance difference, or another kind of difference, that would conclusively favor one syntax over the other.
Thanks for your suggestions.
This question is actually answered pretty good in these two.
INNER JOIN ON vs WHERE clause
INNER JOIN vs multiple table names in "FROM"
I've included two examples on how three different LINQ expressions will be translated into SQL.
Implicit join:
from prod in Articles
from kat in MainGroups
where kat.MainGroupNo == prod.MainGroupNo
select new { kat.Name, prod.ArticleNo }
Will be translated into
SELECT [t1].[Name], [t0].[ArticleNo]
FROM [dbo].[Article] AS [t0], [dbo].[MainGroup] AS [t1]
WHERE [t1].[MainGroupNo] = [t0].[MainGroupNo]
Inner join:
from prod in Articles
join kat in MainGroups on prod.MainGroupNo equals kat.MainGroupNo
select new { kat.Name, prod.ArticleNo }
Will be translated into
SELECT [t1].[Name], [t0].[ArticleNo]
FROM [dbo].[Article] AS [t0]
INNER JOIN [dbo].[MainGroup] AS [t1] ON [t0].[MainGroupNo] = [t1].[MainGroupNo]
Left outer join:
from prod in Articles
join g1 in MainGroups on prod.MainGroupNo equals g1.MainGroupNo into prodGroup
from kat in prodGroup.DefaultIfEmpty()
select new { kat.Name, prod.ArticleNo }
Will be translated into
SELECT [t1].[Name] AS [Name], [t0].[ArticleNo]
FROM [dbo].[Article] AS [t0]
LEFT OUTER JOIN [dbo].[MainGroup] AS [t1] ON [t0].[MainGroupNo] = [t1].[MainGroupNo]
If you want to test how your expressions will be translated into SQL, I recommend that you try LINQPad. It's an awesome tool for figuring out this kind of stuff.
var result = from a in DB.classA
from b in DB.classB
where a.id.Equals(b.id)
select new{a.b};

How to use leftouter join in entity framework query

How to use leftouter join in entity framework query
I have two table one is item and other is stock available I want to get all items and also get its quantity from stock available table which depend upon the particular department
For example
LINQ Query
var query = (from p in dc.GetTable<Person>()
join pa in dc.GetTable<PersonAddress>() on p.Id equals pa.PersonId into tempAddresses
from addresses in tempAddresses.DefaultIfEmpty()
select new { p.FirstName, p.LastName, addresses.State });
SQL Translation
SELECT [t0].[FirstName], [t0].[LastName], [t1].[State] AS [State]
FROM [dbo].[Person] AS [t0]
LEFT OUTER JOIN [dbo].[PersonAddress] AS [t1] ON [t0].[Id] = [t1].[PersonID]

Linq To Sql Left outer join - filtering null results

I'd like to reproduce the following SQL into C# LinqToSql
SELECT TOP(10) Keywords.*
FROM Keywords
LEFT OUTER JOIN IgnoreWords
ON Keywords.WordID = IgnoreWords.ID
WHERE (DomainID = 16673)
AND (IgnoreWords.Name IS NULL)
ORDER BY [Score] DESC
The following C# Linq gives the right answer.
But I can't help think I'm missing something (a better way of doing it?)
var query = (from keyword in context.Keywords
join ignore in context.IgnoreWords
on keyword.WordID equals ignore.ID into ignored
from i in ignored.DefaultIfEmpty()
where i == null
where keyword.DomainID == ID
orderby keyword.Score descending
select keyword).Take(10);
the SQL produced looks something like this:
SELECT TOP (10)
[t0].[DomainID]
, [t0].[WordID]
, [t0].[Score]
, [t0].[Count]
FROM [dbo].[Keywords] AS [t0]
LEFT OUTER JOIN
( SELECT 1 AS [test]
, [t1].[ID]
FROM [dbo].[IgnoreWords] AS [t1]
) AS [t2]
ON [t0].[WordID] = [t2].[ID]
WHERE ([t0].[DomainID] = 16673)
AND ([t2].[test] IS NULL)
ORDER BY [t0].[Score] DESC
How can I get rid of this redundant inner selection?
It's only slightly more expensive but every bit helps!
I think you can do something like this to eliminate the left join and maybe get more efficiency:
var query = (from keyword in context.Keywords
where keyword.DomainID == ID
&& !(from i in context.IgnoreWords select i.ID).Contains(keyword.WordID)
orderby keyword.Score descending
select keyword)
.Take(10);

Categories

Resources