将左连接的结果加入另一个表

时间:2014-02-04 10:02:53

标签: linq tsql join

我想将查询结果(使用左连接)加入另一个表。 例如:

from c in customers
join o in orders.where(i=>i.qty !=0) 
on c.id equals o.customer_id
into gp 
from subgp in gp.DefaultIfEmpty()
join i in store_items
on subgrp.store_item_id equals i.item_id
into gp1
from subgp1 in gp1.DefaultIfempty()
select new
{
CustomerId = c.id,
CustomerName = c.Name,
ItemInOrder = subgrp1.ItemName
}

我的问题是如果用户没有订单(即无法在Qty!= 0的订单中找到项目),当我尝试加入“subgrp.store_item_id equals i.item_id”时,我得到一个空引用异常。这是说subgrp是null。 有什么想法吗?

1 个答案:

答案 0 :(得分:0)

原因是DefaultIfEmpty实际上会为subgrp返回null。我会做这样的事情:

join i in store_items on (subgrp == null ? new int?() : subgrp.store_item_id) 
                         equals i.item_id 
     into gp1

另外,不要忘记subgrp1.ItemName也可以将subgrp1设为null。所以你必须在那里做一些检查,例如。 ItemInOrder = subgrp1 == null ? null : subgrp1.ItemName

但是,总的来说,您只是尝试使用LINQ,就像使用SQL一样。这是可能的,但是非常笨拙(还要注意你的查询可能会对“真正的”数据库起作用 - 空引用实际上只存在于LINQ到实体中,SQL并不关心。)

例如,您可以像这样重写整个查询:

from c in customers
select new 
{
    CustomerId = c.id,
    CustomerName = c.Name,
    ItemsInOrder = 
      from o in c.Orders
      where o.qty != 0
      join i in store_items on o.store_item_id equals i.item_id
      select i
};

(当然,这只是一个非常简单的例子,你可能会有更复杂的东西,但基本的想法应该是明确的。)

对于像LINQ2SQL或EntityFramework这样的LINQ框架来说,这可能更难以咀嚼(但是那些有自己的构造来简化内容 - 你真的不需要显式连接),但它是一种更清晰的方式来编写查询LINQ2Entities。