2014-11-25 78 views
1

我發現我使用這個模式很多在LINQ:這是什麼LINQ的方法語法,它是一個連接,如果不是,那麼它是什麼?

class Thing 
    { 
     public int ID { get; set; } 
     public int ColorID { get; set; } 
    } 
    class Color 
    { 
     public int ID { get; set; } 
     public string Description { get; set; } 
    } 
    static void Main() 
    { 
     var things = new List<Thing> { new Thing { ID = 1, ColorID = 1 }, new Thing { ID = 2, ColorID = 1 }, new Thing { ID = 3, ColorID = 2 }, new Thing { ID = 4, ColorID = 1 } }; 
     var colors = new List<Color> { new Color { ID = 1, Description = "red" }, new Color { ID = 2, Description = "green" }, new Color { ID = 3, Description = "blue" } }; 
     var joined = (from thing in things 
         from color in colors 
         where thing.ColorID == color.ID 
         select new { ID = thing.ID, Color = color.Description }).ToArray(); 
     foreach (var thing in joined) 
     { 
      Console.WriteLine("(" + thing.ID + ", " + thing.Color + ")"); 
     } 
     //Writes: 
     //(1, red) 
     //(2, red) 
     //(3, green 
     //(4, red) 
    } 

它的核心,查詢語法的四大行,感覺非常像一個INNER JOIN,我可能會在TSQL寫的,但是當我看着examples of LINQ query syntax for joins他們使用單詞join,而上面的LINQ沒有。

上面的LINQ正在執行的'連接'是什麼,我將如何在LINQ方法語法中重寫它?

回答

3

根據LINQ的理解,它根本不執行連接。它只是基於兩個屬性進行篩選,其中一個發生來自一個範圍變量,而另一個發生來自另一個。在方法的語法你會寫爲:

var joined = things.SelectMany(thing => colors, 
           (thing, color) => new { thing, color }) 
        .Where(pair => pair.thing.ColorID == pair.color.ID) 
        .Select(pair => new { ID = pair.thing.ID, 
             Color = pair.color.Description }) 
        .ToArray(); 

這裏的pair有效地自動編譯器引入作爲透明標識符。這不是由於在where中的過濾,而是由於在第一個使用SelectMany之後有多個from子句......每個from子句,並且引入了透明標識符以允許您引用多個範圍變量(thingcolor ),它們組成一個單獨的對象,以便流水線的每個階段只能理論上處理一個值。

需要注意的是,當你有兩個from條款:

from person in people 
from book in books 

...這行爲像笛卡爾加入...但LINQ允許一些更微妙的,如:

from person in people 
from book in person.Books 

換句話說,第二序列可以取決於來自第一序列的「當前」值。流水線的任何後續階段(例如,whereselect)作用於每對:一個來自第一序列,然後一個來自第二序列中的元素產生的第二序列。

+0

謝謝約翰。我通過專門編寫查詢語法來開始LINQ,但最近我一直在交換方法語法,因爲它通常更清晰,更像C#一樣,但在這種情況下,它更簡單得多,儘管它有助於解釋發生了什麼。 – dumbledad 2014-11-25 14:25:03

+0

我正要回答它執行內部循環連接。語法非常多,如何在SQL-89中編寫內部連接。但你說它不是。 – Magnus 2014-11-25 14:25:34

+0

@Magnus:它可能被*翻譯成LINQ to SQL的「內部循環連接」,當然...... – 2014-11-25 14:27:46