首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

LINQ to SQL Join 操作全解析:Join、SelectMany、GroupJoin 與 Left Outer Join 模式

     編輯:關於C#

三種 Join API 概覽

LINQ to SQL 提供三個 Join 相關 API:

  • Join:內部聯結(Inner Join)
  • SelectMany:一對多導航屬性聯結(隱式 Left Join)
  • GroupJoin:群組聯結(對應 join ... into)

查詢運算式會自動轉換為對應 API。

Inner Join:Join 方法


var q = from c in db.Customers
        join o in db.Orders on c.CustomerID equals o.CustomerID
        select new { c.CustomerID, o.EmployeeID };

轉換為:


db.Customers.Join(db.Orders, 
    c => c.CustomerID, 
    o => o.CustomerID, 
    (c, o) => new { c.CustomerID, o.EmployeeID });

參數順序固定:外部序列鍵選擇器、內部序列鍵選擇器、結果選擇器。SQL 生成標準 INNER JOIN。

SelectMany:導航屬性隱式聯結

條件:無 join/into 且出現 EntitySet(一對多導航屬性)。

範例 1:基本一對多


from c in db.Customers
from o in c.Orders          // c.Orders 為 EntitySet
where c.City == "London"
select o;

對應映射屬性:


[Association(Name="Order_OrderDetail", Storage="_OrderDetails", OtherKey="OrderID")]
[Association(Name="Order_OrderDetail", Storage="_Order", ThisKey="OrderID", IsForeignKey=true)]

範例 2:跨表條件產生 Left Outer Join


from p in db.Products
where p.Supplier.Country == "USA" && p.UnitsInStock == 0
select p;

生成 SQL 為 LEFT OUTER JOIN Suppliers,最簡潔的 Left Join 寫法。

範例 3:多對多關係


from e in db.Employees
from et in e.EmployeeTerritories
where e.City == "Seattle"
select new { e.FirstName, e.LastName, et.Territory.TerritoryDescription };

涉及三表 Employees - EmployeeTerritories - Territories,生成 CROSS JOIN + INNER JOIN。

範例 4:自我關聯


from e1 in db.Employees
from e2 in e1.Employees
where e1.City == e2.City
select new { ... };

生成舊式逗號聯結語法。

Group Join:GroupJoin 與 join ... into

查詢運算式含 join ... into 時轉換為 GroupJoin。

基本群組聯結:統計每位客戶訂單數


var q = from c in db.Customers
        join o in db.Orders on c.CustomerID equals o.CustomerID into orders
        select new { c.ContactName, OrderCount = orders.Count() };

into orders 將對應的訂單群組重命名為 orders,可在 select 中呼叫聚合函數。生成 SQL 使用子查詢 SELECT COUNT(*) ...。

多重 GroupJoin


join o in db.Orders ... into ords
join e in db.Employees ... into emps
select new { c.ContactName, ords=ords.Count(), emps=emps.Count() };

標準 Left Outer Join 模式


var q = from e in db.Employees
        join o in db.Orders on e equals o.Employee into ords
        from o in ords.DefaultIfEmpty()
        select new { e.FirstName, e.LastName, Order = o };
  1. join ... into ords 群組聯結
  2. from o in ords.DefaultIfEmpty() 展開群組,無對應時產生 null
  3. 最終 Order 為單一物件而非集合

生成 SQL 為標準 LEFT OUTER JOIN。

let 子句與 GroupJoin 結合


var q = from c in db.Customers
        join o in db.Orders on c.CustomerID equals o.CustomerID into ords
        let z = c.City + c.Country
        from o in ords
        select new { c.ContactName, o.OrderID, z };

let 類似 into 為運算結果重命名,位置可在第一個 from 後、select 前任意處。

複合鍵聯結


join d in db.OrderDetails
on new { o.OrderID, p.ProductID } equals new { d.OrderID, d.ProductID }
into details

使用匿名型別表示複合鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved