2013-05-07 74 views
0

我希望在過濾其中一個表時連接兩個表。像關於將關聯表加入關鍵字

var matching = from a in ctx.A 
       join b in ctx.B on a.BId equals b.Id 
       where idList.Contains(b.Id) 
       select a; 

工作正常不過,如果我還利用into關鍵字來命名連接結果

var matching = from a in ctx.A 
       join b in ctx.B on a.BId equals b.Id into c 
       where idList.Contains(b.Id) 
       select a; 

我得到一個編譯錯誤告訴我

名稱' b'在當前情況下不存在

H不過,我可以在那個時候參考a,以及'c',沒有問題。

爲什麼到了這一點,我該如何申請條款b

回答

4

爲什麼恰好

因爲join into條款後,通過該條款引入的範圍變量不在範圍內 - 而以前的變量。不要忘記,您正在將納入c,因此b的每個值都是該組值的一部分(c)。

我該如何在b中應用where子句?

通過做早期:

var matching = from a in ctx.A 
       join b in ctx.B.Where(x => idList.Contains(x.Id)) 
       on a.BId equals b.Id into c 
       where c.Any() 
       select a; 

編輯:這可以投入稍多查詢表達式爲導向代碼:

var matchingBs = from b in ctx.B 
       where idList.Contains(b.Id) 
       select b; 
var matching = from a in ctx.A 
       join b in matchingBs 
       on a.BId equals b.Id into c 
       where c.Any() 
       select a; 

(您可以使用嵌套查詢表達式,但我不喜歡那些一般)。

或使用Anyc

var matching = from a in ctx.A 
       join b in ctx.B on a.BId equals b.Id into c 
       where c.Any(b => idList.Contains(b.Id)) 
       select a; 

甚至:

var matching = from a in ctx.A 
       where ctx.B.Any(b => idList.Contains(x.Id) && 
            a.BId == b.Id) 
       select a; 

可以將它改寫爲:

var matching = ctx.A.Where(a => ctx.B.Any(b => idList.Contains(x.Id) && 
              a.BId == b.Id)); 

瞭解joinjoin into結果之間的差異是很重要的 - 第一次創建「成對」加入;第二個創建一個連接,其中額外範圍變量的結果是一組匹配項。

+0

所有的例子都需要至少一些Linq方法語法。這不能單獨用查詢語法表達嗎? – 2013-05-08 17:24:36

+0

@EricJ:我不認爲你可以擺脫使用'任何'。雖然我會編輯一個「最低限度的方法語法」版本。 – 2013-05-08 17:32:14