Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LEFT JOIN in LINQ to entities?

I'm trying out LINQ to entities.

I have a problem with the following: I want it to do this:

SELECT       T_Benutzer.BE_User     ,T_Benutzer_Benutzergruppen.BEBG_BE FROM T_Benutzer  LEFT JOIN T_Benutzer_Benutzergruppen     ON T_Benutzer_Benutzergruppen.BEBG_BE = T_Benutzer.BE_ID  

the closest thing I've come to is this:

        var lol = (             from u in Repo.T_Benutzer              //where u.BE_ID == 1             from o in Repo.T_Benutzer_Benutzergruppen.DefaultIfEmpty()                 // on u.BE_ID equals o.BEBG_BE              where (u.BE_ID == o.BEBG_BE || o.BEBG_BE == null)              //join bg in Repo.T_Benutzergruppen.DefaultIfEmpty()             //    on o.BEBG_BG equals bg.ID              //where bg.ID == 899               orderby                 u.BE_Name ascending                 //, bg.Name descending              //select u              select new             {                  u.BE_User                 ,o.BEBG_BG                 //, bg.Name              }          ).ToList(); 

But this generates the same results as an inner join, and not a left join.
Moreover, it creates this completely crazy SQL:

SELECT       [Extent1].[BE_ID] AS [BE_ID]     ,[Extent1].[BE_User] AS [BE_User]     ,[Join1].[BEBG_BG] AS [BEBG_BG] FROM  [dbo].[T_Benutzer] AS [Extent1]  CROSS JOIN   (     SELECT           [Extent2].[BEBG_BE] AS [BEBG_BE]         ,[Extent2].[BEBG_BG] AS [BEBG_BG]     FROM ( SELECT 1 AS X ) AS [SingleRowTable1]     LEFT OUTER JOIN [dbo].[T_Benutzer_Benutzergruppen] AS [Extent2]          ON 1 = 1  ) AS [Join1]  WHERE [Extent1].[BE_ID] = [Join1].[BEBG_BE]  OR [Join1].[BEBG_BE] IS NULL  ORDER BY [Extent1].[BE_Name] ASC 

How can I do a left join in LINQ-2-entities in a way where another person can still understand what's being done in that code ?

and most-preferably where the generated SQL looks like:

SELECT       T_Benutzer.BE_User     ,T_Benutzer_Benutzergruppen.BEBG_BE FROM T_Benutzer  LEFT JOIN T_Benutzer_Benutzergruppen     ON T_Benutzer_Benutzergruppen.BEBG_BE = T_Benutzer.BE_ID  
like image 645
Stefan Steiger Avatar asked Oct 14 '13 08:10

Stefan Steiger


People also ask

Can we use left join in LINQ?

You can use LINQ to perform a left outer join by calling the DefaultIfEmpty method on the results of a group join.

Which join is valid in LINQ?

LINQ Inner Join Inner Join produces the result from two or more than two tables. So, basically we are meant to get the records from both tables based on matching conditions. Basically in SQL, we use the INNER JOIN keyword to make relationship between both tables. The following is the Linq query for above SQL query.

Is LINQ join inner or outer?

When you use the LINQ join clause in the query expression syntax to combine two sets of related information, you perform an inner join. This means that you provide an expression that determines for each item in the first sequence, the matching items in the second.


1 Answers

Ah, got it myselfs.
The quirks and quarks of LINQ-2-entities.
This looks most understandable:

var query2 = (     from users in Repo.T_Benutzer     from mappings in Repo.T_Benutzer_Benutzergruppen         .Where(mapping => mapping.BEBG_BE == users.BE_ID).DefaultIfEmpty()     from groups in Repo.T_Benutzergruppen         .Where(gruppe => gruppe.ID == mappings.BEBG_BG).DefaultIfEmpty()     //where users.BE_Name.Contains(keyword)     // //|| mappings.BEBG_BE.Equals(666)       //|| mappings.BEBG_BE == 666      //|| groups.Name.Contains(keyword)      select new     {          UserId = users.BE_ID         ,UserName = users.BE_User         ,UserGroupId = mappings.BEBG_BG         ,GroupName = groups.Name     }  );   var xy = (query2).ToList(); 

Remove the .DefaultIfEmpty(), and you get an inner join.
That was what I was looking for.

like image 122
Stefan Steiger Avatar answered Sep 29 '22 14:09

Stefan Steiger