Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

left outer join in lambda/method syntax in Linq [duplicate]

Tags:

c#

.net

linq

Possible Duplicate:
How do you perform a left outer join using linq extension methods

I can't find a left outer join example of Linq lambda (with extension methods), at least, not a clear one.

Let's say I have the following table:

Parent {     PID     // PK }  Child {     CID     // PK     PID     // FK     Text } 

I want to join Parent with Child, and for every child missing, I want the default value for Text to be "[[Empty]]". How can I do this with linq lambda syntax?

I currently have the following:

var source = lParent.GroupJoin(     lChild,     p => p.PID,     c => c.PID,     (p, g) =>         new // ParentChildJoined         {             PID = p.PID;             // How do I add child values here?         }); 
like image 510
NomenNescio Avatar asked Aug 22 '12 14:08

NomenNescio


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.

Is GroupJoin left join?

This is actually not nearly as crazy as it seems. Basically GroupJoin does the left outer join, the SelectMany part is only needed depending on what you want to select.

Is Linq join inner or outer?

One commonly used feature of Language-Integrated Query (LINQ) is the facility to combine two sequences of related data using joins. The standard join operation provides an inner join but with a minor modification can be changed to give a left outer join.

What is difference between left outer join and left join?

There really is no difference between a LEFT JOIN and a LEFT OUTER JOIN. Both versions of the syntax will produce the exact same result in PL/SQL. Some people do recommend including outer in a LEFT JOIN clause so it's clear that you're creating an outer join, but that's entirely optional.


2 Answers

You're close. The following will select PID, CID and Text for each child, and PID, CID = -1 and Text = "[[Empty]]" for each parent with no children:

var source = lParent.GroupJoin(     lChild,     p => p.PID,     c => c.PID,     (p, g) => g         .Select(c => new { PID = p.PID, CID = c.CID, Text = c.Text })         .DefaultIfEmpty(new { PID = p.PID, CID = -1, Text = "[[Empty]]" }))     .SelectMany(g => g); 
like image 98
Rawling Avatar answered Sep 19 '22 15:09

Rawling


from p in Parent join c in Child on p.PID equals c.PID into g from c in g.DefaultIfEmpty() select new  {    p.PID,    CID = c != null ? (int?)c.CID : null, // Could be null    Text = c != null ? c.Text : "[[Empty]]" } 

With lambda:

class ChildResult {    public int PID { get; set; }    public int? CID { get; set; }    public string Text { get; set; } }  lParent.SelectMany(p => p.Childs.Any() ?   p.Childs.Select(c => new ChildResult() { PID = c.PID, CID = c.CID, Text = c.Text }) :   new [] { new ChildResult() { PID = p.PID, CID = null, Text = "[[Empty]]" } } ); 
like image 21
Amiram Korach Avatar answered Sep 23 '22 15:09

Amiram Korach