Linq中join & group join & left join 的用法
我們在做SQL查詢的時候經常會用到Inner Join,Left Join,笛卡爾積等等,連線方式的概念方面我想也不用給予太多解釋,
我們今天的重點是讓大家熟悉LINQ是如何使用Join來實現常用的表連線的。
建立測試用類:
class Customer { public int CustomerId { get; set; } public string Name { get; set; } public int Age { get; set; } } class Product { public int ProductId { get; set; } public string Name { get; set; } public string Origin { get; set; } } class Order { public int OrderId { get; set; } public int CustomerId { get; set; } public List<Product> Products { get; set; } }
我們用以下例子來熟悉 Join 關鍵字的用法。
1.Inner Join:
CreateEntities(); var query = from c in customers join o in orders on c.CustomerId equals o.CustomerId where o.OrderId == 2 select c; foreach (var customer in query) { Console.WriteLine("Id:{0}, Name:{1}", customer.CustomerId, customer.Name); }
執行結果:
Id:1, Name:CA
上面這個是常見的內連線的例子,和SQL語法也很相似,但有以下幾點要注意:
(1).連線條件: c.CustomerId equals o.CustomerId 只能使用 equals 不能用 =,==,等於 等表示。
以為LINQ的設計者認為 幾乎所有的連線條件都是 = 條件不會出現 >,<,!= 等情況因此使用了個關鍵字來描述表連線條件。
(2).條件順序:c.CustomerId equals o.CustomerId ,range variable: c 和b之前的順序不能顛倒。
2.Group Join:
也許大家對Group Join的概念不太瞭解,沒關係讓我們通過例子來認識它:
CreateEntities();
var query = from c in customers
join o in orders on c.CustomerId equals o.CustomerId into os
select new { c, os };
foreach (var item in query)
{
Console.WriteLine("Customer Id:{0}, Name:{1}", item.c.CustomerId, item.c.Name);
foreach (var o in item.os)
{
Console.WriteLine("--Order Id:{0}", o.OrderId);
}
}
結果:
Customer Id:1, Name:CA
--Order Id:1
--Order Id:2
Customer Id:2, Name:CB
--Order Id:4
Customer Id:3, Name:CC
--Order Id:3
Customer Id:4, Name:CD
Press any key to continue . . .
以上查詢返回的結果:和Group By 返回的結果非常的相似:一個KEY物件對應一個集合。
要實現Group Join我們要引入一個關鍵字:into
但使用時要注意一下幾點:
(1).使用into 關鍵字後 join 後面的 range variable:o 在後面的表示式塊中就失去了作用域。
(2).range variable:os 通常情況下都是IEnumerable<T>型別的。
3.Left Join:
Left Join 我們在SQL裡經常用到,讓我們來看看LINQ裡怎麼實現它:
CreateEntities();
var query = from c in customers
join o in orders on c.CustomerId equals o.CustomerId into os
from o2 in os.DefaultIfEmpty(
new Order { OrderId = 0, CustomerId = 0, Products = new List<Product>() })
select new { c, o2 };
foreach (var item in query)
{
Console.WriteLine("Customer Id:{0}, Name:{1}--Order Id:{0}",
item.c.CustomerId, item.o2.OrderId);
}
結果:
Customer Id:1, Name:1--Order Id:1
Customer Id:1, Name:2--Order Id:1
Customer Id:2, Name:4--Order Id:2
Customer Id:3, Name:3--Order Id:3
Customer Id:4, Name:0--Order Id:4
Press any key to continue . . .
我們可以看到Left Outer Join 的語法進一步的複雜化了,結果也有細微的不同。
(1).從語法上:
from o2 in os.DefaultIfEmpty(
new Order { OrderId = 0, CustomerId = 0, Products = new List<Product>() })
主要區別在於以上者1句語句。查詢方法DefaultIfEmpty 用於定義當查詢記錄為空時,預定義預設值。再從其集合中取出子元素。
(2).從結果上: 我們在遍歷查詢結果時可以發現Left Join相似於Inner Join結果都是“平面”的,然而Group Join返回的結果具有層次性。
題外:
由於C#是面向物件的,往往會通過物件與物件間的外系來實現資料間關係。有時表達2個之間的關係也可以不使用Join關鍵字,
因此Join關鍵字其實在實際LINQ查詢表示式中用的不是很多。
站內連線: