2012-02-04 121 views
4

我是新來的LINQ,兩種環境下使用時對象,並有一個關於from條款問題:外連接LINQ

1)進行交叉連接,如查詢波紋管

var q1 = from person in people 
     from job in jobs 
     select new {person, job} 

2)以執行一個外部聯接

var q2 = from person in people 
    join pet in pets on person equals pet.Owner into gj 
    from subpet in gj 
    select new { OwnerName = person.FirstName, PetName = subpet.Name }; 

確實從子句第二充當交叉連接或它取決於上下文中計算的?因爲 Q1會產生people.Count * jobs.Count元件 但Q2將產生僅people.Count

回答

3

根據MS文檔,使第二查詢左外連接,你應該使用DefaultIfEmpty方法看到here。 from子句始終以相同的方式進行評估:它會返回序列中的每個元素,它是預定義的源還是上下文變量。

編輯:我會嘗試從一開始來解釋。起初你內心加入(羣體加入,具體)人和寵物。然後你從結果集合(實際上是person-pets集)中選擇新的匿名對象,從gj set元素中獲取人名(和gj set元素中的每個寵物)的子名稱。我認爲第二個來自gj的選擇,並且每個人已經是gj集合元素的一部分,所以不會進行交叉連接。如果您在第二個from子句中調用gj.DefaultIfEmpty()方法,則沒有任何寵物的人(在gj set元素中有空寵物集合)將被添加到結果集中。你可以閱讀下面的文章,以更好地理解它:

+0

對於查詢'q1'來說,第二個'from'充當來自人員和來自作業的元素之間的交叉連接,第二個查詢的情況如何? – 2012-02-04 13:28:57

+0

在我看來,'from'子句不是作爲交叉連接,而是select。 'from'只是進行交叉連接的手段,因爲它提供了序列中的元素。在第二個示例中,您將person-pet內部聯接生成爲gj,並使用第二個「from」從結果集中選擇每個元素,僅此而已,沒有什麼更少的。要執行一個左外連接,你應該爲沒有寵物的人替換正確的值(來自gj set)。 – 2012-02-04 13:47:06

+0

是否意味着'from'作爲foreach循環,而第二個'from'是第一個內部foreach? – 2012-02-04 14:08:42

0

join通常用於基於匹配密鑰的兩個序列的元素相關,所以它是通常一個內連接,但它取決於你定義的匹配,例如下面會產生交叉聯接:

List<int> A = new List<int> { 1, 2, 3, 4, 5 }; 
List<int> B = new List<int> { 1, 2, 3, 4, 5 }; 
var c = (from a in A join b in B on 1 equals 1 select new { a, b }).ToList(); 
+0

我的問題是關於'from'條款(一個Seconde系列中查詢)不'join',它是作用在這兩個查詢相同的方式(Q1和Q2),或者它產生交叉連接的第一個和一個外部連接的第二個? – 2012-02-04 11:33:49

0

基於上下文進行評估。如果不是,您將無法使用上下文變量,如gj。但是,如果您不使用該上下文,就像在第一個查詢中那樣,它的行爲與交叉連接相同。

你說的第二個查詢爲您提供了元素的意外數字。也許你不應該把注意力集中在那個上面,而是要看你得到了什麼元素,以及這與你所期待的有什麼不同。

+0

對於查詢'q1'來說,第二個'from'是來自人員和來自作業的元素之間的交叉連接,第二個查詢的情況如何? – 2012-02-04 13:37:29