Home > Back-end >  Linq Left Join Fails on List when right side is empty
Linq Left Join Fails on List when right side is empty

Time:10-30

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;

Sample program


Updated:

In case you are accessing RIGHT table (rs), you need to do null checking for rs first and next handling for null case.

  • Related