C#EF - 使用过滤器在包含的实体上进行左连接

时间:2014-07-28 17:50:08

标签: c# sql linq entity-framework linq-to-entities

我有以下表格结构

Orders
 OrderID PK

PartyAddresses
 PartyAddressID PK

然后我有一个将PartyAddress连接到订单的连接表

OrderAddresses
 OrderAddressID PK
 OrderID FK to Orders
 PartyAddressID FK to PartyAddresses
 AddressType  

我想要转换的sql语句是

SELECT 
 * 
FROM 
Orders o  LEFT JOIN OrdersAddresses oa
       ON 
    o.OrderID = oa.OrderID
       LEFT JOIN PartyAddresses pa
          ON
       pa.PartyAddressID = oa.PartyAddressID
WHERE
    oa.AddressType = 'SHIP'

我无法确定将其复制到Linq lambda语句中

我已经能够通过从OrdersAddress表开始检索我想要的数据

OrdersAddresses.Include("Orders").Include("PartyAddresses").Where(oa=>oa.AddressType=="Ship");

但我需要IEnumerable<Orders>

的结果

更新

我想重新解释一下我的问题 - 给出以下存储库函数

public IQueryable<Orders> OrdersWithAddresses()
{
    return _context.Orders.Include("OrdersAddresses").Include("OrdersAddresses.PartyAddresses");
}

如何添加到表达式树只能实际返回“SHIP”

的订单地址

1 个答案:

答案 0 :(得分:0)

这不是我的头脑,但我相信它应该有效。请注意,我已经删除了第一个LEFT JOIN,因为WHERE子句无论如何都会过滤掉NULL,因此很容易进行正常连接:

var results = from o in db.Orders
              join oa in db.OrdersAddresses on o.OrderID equals oa.OrderID
              join pa in db.PartyAddresses on oa.PartyAddressID equals pa.PartyAddressID into pas
              from p in pas.DefaultIfEmpty()
              where oa.AddressType == "SHIP"
              select new { o, oa, p };

更新

或者,您可以修改存储库函数以包含Where子句:

public IQueryable<Orders> OrdersWithAddresses(Func<Orders, bool> predicate)
{
    var orders = _context.Orders.Include("OrdersAddresses").Include("OrdersAddresses.PartyAddresses");

    if(predicate != null)
        return orders.Where(predicate);

    return orders;
}

并调用这样的函数:

var orders = OrdersWithAddresses(o => o.AddressType = "SHIP");