2010-03-10 60 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()