2010-11-01 22 views
18

我真想做這樣的事情:如何在LINQ to Entities中執行SQL「Where Exists」?

Select * 
from A join B on A.key = B.key join C on B.key = C.key -- propagated keys 
where exists (select null from B where A.key = B.key and B.Name = "Joe") and 
     exists (select null from C where B.key = C.key and C.Name = "Kim") 

將LINQ的聲明是什麼樣的使用實體框架4和C#?

更新:

顯然。載有()會產生 「凡存在」 的結果。因此,另一種嘗試
(我不知道這甚至會編譯LOL):

var inner1 = from recordB in B 
      where recordB.Name = "Joe" 
      select recordB.key; 

var inner2 = from recordC in C 
      where recordC.Name = "Kim" 
      select recordC.key; 

var result = from recordA in A 
      where inner1.Contains(recordA.key) && 
        inner2.Contains(recordA.key) 
      select recordA; 

編輯:哇,這是什麼樣的實際工作:

var result = from A in Products 
      where A.kfield1 == 1 && A.kfield2 == 2 && 
        (from B in Btable 
        where B.otherid == "Joe" && // field I want to select by 
          B.kfield1 == A.kfield1 &&  
          B.kfield2 == A.kfield2 // Can keep adding keys here 
        select A.identifier // unique identity field 
        ).Contains(A.identifier) && 
        (from C in Ctable 
        where C.otherid == "Kim" && // field I want to select by 
          C.kfield1 == A.kfield1 &&  
          C.kfield2 == A.kfield2 // Can keep adding keys here 
        select A.identifier // unique identity field 
        ).Contains(A.identifier) 
      select A; 

這產生這個SQL:

SELECT [t0].[identifier], [t0].* 
FROM [A] AS [t0] 
WHERE ([t0].[kfield1] = @p0) AND ([t0].[kfield2] = @p1) AND (EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [B] AS [t1] 
    WHERE ([t0].[identifier] = [t0].[identifier]) AND ([t1].[otherid] = @p2) AND 
      ([t1].[kfield1] = [t0].[kfield1]) AND 
      ([t1].[kfield2] = [t0].[kfield2]))) AND (EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [C] AS [t2] 
    WHERE ([t0].[identifier] = [t0].[identifier]) AND ([t2].[otherid] = @p3) AND 
      ([t2].[kfield1] = [t0].[kfield1]) AND 
      ([t2].[kfiekd2] = [t0].[kfield2]))) 

這是我想要的。請注意[t0]。[identifier] = [t0]。[identifier],它過濾掉null值,因爲null不會與包括它自身在內的任何東西進行比較(在SQL中)

回答

26

.Any()擴展方法通常映射到exists

+0

這是一件很好的事情要知道。到目前爲止,我在互聯網上發現的唯一一件事就是SO答案之外的.Contains()。我見過。所有()使用過,但我沒有把兩個和兩個放在一起。 – 2010-11-03 19:15:29

+0

這個問題最終向我展示瞭如下代碼:http://stackoverflow.com/questions/4084102/how-would-i-improve-this-7-line-linq-query-that-acts-as-a-規範 – 2010-11-03 19:16:17

0

您是否嘗試將exists條件添加到你的加入?

from a in context.AEntity 
Join B in context.BEntity on A.Key equals B.Key && B.Name == "Joe" 
Join C in context.CEntity on B.Key equals C.Key && C.Name == "Kim"; 

不知道這是否會奏效,但值得一試。

+0

不,它不會工作。 'on'子句只接受'equals'表達式 – 2010-11-02 00:38:23

+0

再看看你的問題,我不確定我明白你爲什麼首先使用'exists'。爲什麼不只是添加'where B.Name ==「Joe」&& C.Name ==「Kim」'? – 2010-11-02 00:53:55

+0

因爲我正在嘗試篩選嵌套結果的現有查詢。我需要通過嵌套部分進行過濾。我能想到的唯一方法就是使用Where存在(如果這是真的,請取得記錄)。 – 2010-11-02 01:03:00