我正试图对两个列表执行左联接,我的查询遇到了一个问题,如果右列表为空,则左联接将失败。我如何更改查询,以便即使列表为空,左联接仍能工作
示例查询:
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解决问题https://dotnetfiddle.net/Brh74F
现在我可以用if语句来避免这个问题,但我真的希望能够在纯linq中实现适当的左联接。
删除中的.DefaultIfEmpty()
join rs in reserved.DefaultIfEmpty()
删除.DefaultIfEmpty()
的原因是:
public static System.Collections.Generic.IEnumerable<TSource> DefaultIfEmpty<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, TSource defaultValue);
返回
IEnumerable<TSource>
如果源为空,则包含defaultValue的IEnumerable;否则,来源。
由于您没有将defaultValue
传递给.DefaultIfEmpty()
,因此当reserved
为空列表时,它将返回null
。
和select r
,因为您希望从LEFT表返回数据。
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;
示例程序
更新:
如果您正在访问RIGHT表(rs
),则需要首先对rs
执行null checking
,然后再处理null情况。