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? });
You can use LINQ to perform a left outer join by calling the DefaultIfEmpty method on the results of a group 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.
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.
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.
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);
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]]" } } );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With