2010-03-10 81 views
3

我有以下LINQ查询(适用于Northwind数据库)LINQ到与与运营商的SQL在同一领域

(from od in OrderDetails 
where od.ProductID == 11 || od.ProductID == 42 
select od.OrderID).Distinct() 

这给了我一个订单ID列表(67项),其中订单包括产品11或42.我如何重写查询给我一个订单ID列表,其中订单包括产品11和42?结果列表应该只有一个订单(orderid = 10248)

很明显,以下查询不会返回任何订单。

(from od in OrderDetails 
    where od.ProductID == 11 && od.ProductID == 42 
    select od.OrderID).Distinct() 

这是一个sql查询,做这项工作,但什么是最好的(或最有效的)写在linq的方式?

SELECT DISTINCT OrderID 
    FROM   [Order Details] 
    WHERE  (OrderID IN 
           (SELECT  OrderID 
           FROM   [Order Details] AS OD1 
           WHERE  (ProductID = 11))) AND (OrderID IN 
           (SELECT  OrderID 
           FROM   [Order Details] AS OD2 
           WHERE  (ProductID = 42))) 

[编辑]

感谢klausbyskov他的解决方案。从那以后,我能够构建一个表达式(使用PredicateBuilder),它可以获取产品ID的动态列表,在where子句中使用它们并返回订单列表。这里如果有人感兴趣。

public static Expression<Func<Order, bool>> WhereProductIdListEqualsAnd(int[] productIds) 
{ 
    var condition = PredicateBuilder.True<Order>(); 

    foreach (var id in productIds) 
    { 
     condition = condition.And(o => o.OrderDetails.Any(od => od.ProductId == id)); 
    } 

    return condition; 
} 

回答

3

开始查询订单关系代替:

var result = Orders.Where(o => o.OrderDetails.Any(od => od.ProductId == 11) 
          && o.OrderDetails.Any(od => od.ProductId == 42)); 
+0

伟大的一点 - 我在想同样的事情,但想通了也许他没有访问该关系 – 2010-03-10 16:20:32

+0

嗨klausbyskov,谢谢你的答案。它完美的作品。我可以跟进另一个问题吗?如果我在运行时得到一个动态的productids列表 - 有什么办法可以让他们进入linq查询 - 可能是通过使用PredicateBuilder? – Stuart 2010-03-10 17:35:20

1

您可以简化到这个过程的一个查询,但是这会工作:

var o1 = OrderDetails.Where(od => od.ProductID == 11).Select(od => od.OrderID); 
var o2 = OrderDetails.Where(od => od.ProductID == 42).Select(od => od.OrderID); 
var intersection = o1.Intersect(o2); 

做的另一个(可能更有效)的方式将是通过加入:

(from o1 in OrderDetails 
join o2 in OrderDetails on o1.OrderID equals o2.OrderID 
where o1.ProductID == 11 and o2.ProductID == 42 
select o1.OrderID).Distinct()