I'm trying to perform a left join on 2 lists, I'm running into a problem with my query where the left join fails if the right list is empty. How can I change the query so the left join will still work even if the list is empty
Example query:
var received = new List<Foo>{new Foo{ProductId=1,WarehouseSectionId=2, qty= 7}};
var reserved = new List<Foo>{};
var leftOuterJoin = from r in received
join rs in reserved.DefaultIfEmpty()
on new {a = r.ProductId, b = r.WarehouseSectionId } equals new { a = rs.ProductId, b = rs.WarehouseSectionId } into joinedL
from rs in joinedL.DefaultIfEmpty()
select new Foo{
qty = rs != null ? r.qty rs.qty: r.qty};
.NetFiddle Implementing the problem https://dotnetfiddle.net/Brh74F
Right now I can avoid this issue with a if statement but I would really like to be able to implement a proper left join in pure linq.
CodePudding user response:
Remove .DefaultIfEmpty()
in
join rs in reserved.DefaultIfEmpty()
The reason why remove .DefaultIfEmpty()
as:
public static System.Collections.Generic.IEnumerable<TSource> DefaultIfEmpty<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, TSource defaultValue);
Returns
IEnumerable<TSource>
An IEnumerable that contains defaultValue if source is empty; otherwise, source.
Since you didn't pass defaultValue
to .DefaultIfEmpty()
, it will return null
when reserved
is empty list.
And select r
since you want to return data from the LEFT table.
var leftOuterJoin = from r in received
join rs in reserved
on new { a = r.ProductId, b = r.WarehouseSectionId } equals new { a = rs.ProductId, b = rs.WarehouseSectionId } into joinedL
from rs in joinedL.DefaultIfEmpty()
select r;
Updated:
In case you are accessing RIGHT table (rs
), you need to do null checking
for rs
first and next handling for null case.