聯接是指將一個資料來源物件與另一個資料來源物件進行關聯或聯合的操作。這兩個資料來源物件通過一個共同的值或屬性進行關聯。
LINQ的聯接操作符將包含可匹配(或相同)關鍵字的兩個或多個資料來源中的值進行匹配。
LINQ有兩個聯接操作符:join和groupjoin。
1. join
join操作符類似於T-SQL中的inner join,將一個資料來源與另一個資料來源相聯接,根據兩個資料來源中相等的值進行匹配。
1>. 原型定義
public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector);
public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer);
2>. 示例
var expr = from p in context.Products join c in context.Categories on p.CategoryID equals c.CategoryID where p.CategoryID == 1 select p;
var expr = context.Cities.Join(context.Provinces, p => p.ProvinceID, c => c.ProvinceID, (p, c) => p) .Where(c => c.ProvinceID == 5);
var query = from p in context.Products join c in context.Categories on p.CategoryID equals c.CategoryID into pc from c in pc.DefaultIfEmpty() select new { p.ProductID, p.ProductName, p.UnitPrice, CategoryName = c == null ? "No Category" : c.CategoryName };
from c in categories join Product p in products on c.CategoryID equals p.CategoryID select new { c.CategoryName, p.ProductID, p.ProductName } from c in categories join p in c.Products.Cast<Product>() on c.CategoryID equals p.CategoryID select new { c.CategoryName, p.ProductID, p.ProductName } categories.Join( products.Cast<Product>(), c => c.CategoryID, p => p.CategoryID, (c, p) => new { c.CategoryName, p.ProductID, p.ProductName } )
2. GroupJoin
GroupJoin操作符常應用於返回“主鍵物件-外來鍵物件集合”形式的查詢,例如“產品類別-此類別下的所有產品”。
1>.原型定義
public static IQueryable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IQueryable<TOuter> outer, IEnumerable<TInner> inner, Expression<Func<TOuter, TKey>> outerKeySelector, Expression<Func<TInner, TKey>> innerKeySelector, Expression<Func<TOuter, IEnumerable<TInner>, TResult>> resultSelector);
public static IQueryable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IQueryable<TOuter> outer, IEnumerable<TInner> inner, Expression<Func<TOuter, TKey>> outerKeySelector, Expression<Func<TInner, TKey>> innerKeySelector, Expression<Func<TOuter, IEnumerable<TInner>, TResult>> resultSelector, IEqualityComparer<TKey> comparer);
2>. 示例
var expr = from c in context.Categories join p in context.Products on c.CategoryID equals p.ProductID into r select new { c.CategoryName, Products = r }; foreach (var item in expr) { foreach (var product in item.Products) { Console.WriteLine(product.ProductName); } }
var expr = context.Categories.GroupJoin(context.Products, c => c.CategoryID, p => p.CategoryID, (c, p) => new { c.CategoryName, Products = p });