I don't understand how DefaultIfEmpty method works. It is usually used to be reminiscent of left-outer join in LINQ.
DefaultIfEmpty()method must be run on a collection.DefaultIfEmpty()method cannot be run onnullcollection reference.
A code example I don't understand some points that
- Does
p, which is afterintokeyword, refer toproducts? - Is
psthe group of product objects? I mean a sequence of sequences. - If
DefaultIfEmpty()isn't used, doesn't p,from p in ps.DefaultIfEmpty(), run intoselect? Why?
,
#region left-outer-join
string[] categories = {
"Beverages",
"Condiments",
"Vegetables",
"Dairy Products",
"Seafood"
};
List<Product> products = GetProductList();
var q = from c in categories
join p in products on c equals p.Category into ps
from p in ps.DefaultIfEmpty()
select (Category: c, ProductName: p == null ? "(No products)" : p.ProductName);
foreach (var v in q)
{
Console.WriteLine($"{v.ProductName}: {v.Category}");
}
#endregion
Code from 101 Examples of LINQ.
I ain't generally answer my own question, however, I think some people might find the question somewhat intricate. In the first step, the working logic of the
DefaultIfEmptymethod group should be figured out(LINQ doesn't support its overloaded versions, by the by).When being run, seeing that it gives
null entered l2 outresult out. What ifl1.Add(null);is commented in? It is at your disposal, not hard to guess at all.l2has an item which is ofnullsincefoois not one of the building block types likeInt32,String, orChar. If it were, default promotion would be applied to, e.g. for string," "(blank character) is supplied to.Now let's examine the LINQ statement being mentioned.
The followed image, albeit not belonging to C#, helps to get what it means.
In the light of the lazy evaluation, we are now wisely cognizant of the fact that the LINQ using query expression is evaluated when requested, that is, on-demand.
So,
pscontains product items iff the equality expressed atonkeyword ofjoinis satisfied. Further,pshas different product items at each demand of the LINQ expression. Otherwise, unlessDefaultIfEmpty()is used,selectis not hit thereby not iterating over and not yielding anyConsole.WriteLine($"{productName}: {category}");. (Please correct me at this point if I'm wrong.)