JOINS

連線用於組合通過公共金鑰儲存資料的不同列表或表。

與 SQL 一樣,LINQ 支援以下型別的連線:
內部,左側,右側,交叉完整外部連線。

以下示例中使用以下兩個列表:

var first = new List<string>(){ "a","b","c"}; // Left data
var second = new List<string>(){ "a", "c", "d"}; // Right data

(內部聯接

var result = from f in first
             join s in second on f equals s
             select new { f, s };

var result = first.Join(second, 
                        f => f, 
                        s => s,
                        (f, s) => new { f, s });

// Result: {"a","a"}
//         {"c","c"}

左外連線

var leftOuterJoin = from f in first
                    join s in second on f equals s into temp
                    from t in temp.DefaultIfEmpty()
                    select new { First = f, Second = t};

// Or can also do:
var leftOuterJoin = from f in first
                    from s in second.Where(x => x == f).DefaultIfEmpty()
                    select new { First = f, Second = s};

// Result: {"a","a"}
//         {"b", null}  
//         {"c","c"}  

// Left outer join method syntax
var leftOuterJoinFluentSyntax = first.GroupJoin(second,
                                      f => f,
                                      s => s,
                                      (f, s) => new { First = f, Second = s })
                                   .SelectMany(temp => temp.Second.DefaultIfEmpty(),
                                      (f, s) => new { First = f.First, Second = s });

正確的外部加入

var rightOuterJoin = from s in second
                     join f in first on s equals f into temp
                     from t in temp.DefaultIfEmpty()
                     select new {First=t,Second=s};

// Result: {"a","a"}
//         {"c","c"}  
//         {null,"d"}  

交叉加入

var CrossJoin = from f in first
                from s in second
                select new { f, s };

// Result: {"a","a"}
//         {"a","c"}  
//         {"a","d"}  
//         {"b","a"}
//         {"b","c"}  
//         {"b","d"}  
//         {"c","a"}
//         {"c","c"}  
//         {"c","d"}

完全外部加入

var fullOuterjoin = leftOuterJoin.Union(rightOuterJoin);

// Result: {"a","a"}
//         {"b", null}  
//         {"c","c"}  
//         {null,"d"}

實際的例子

上面的示例有一個簡單的資料結構,因此你可以專注於從技術上理解不同的 LINQ 連線,但在現實世界中,你將擁有需要加入的列的表。

在下面的示例中,只使用了一個類 Region,實際上你將連線兩個或多個具有相同鍵的不同表(在此示例中,firstsecond 通過公共金鑰 ID 連線)。

示例: 請考慮以下資料結構:

public class Region 
{
    public Int32 ID;
    public string RegionDescription;
    
    public Region(Int32 pRegionID, string pRegionDescription=null)
    {
        ID = pRegionID; RegionDescription = pRegionDescription;
    }
}

現在準備資料(即填充資料):

// Left data
var first = new List<Region>() 
                 { new Region(1), new Region(3), new Region(4) }; 
// Right data
var second = new List<Region>() 
                 { 
                    new Region(1, "Eastern"),  new Region(2, "Western"),
                    new Region(3, "Northern"), new Region(4, "Southern")
                 }; 

你可以看到,在此示例中,first 不包含任何區域描述,因此你希望從 second 加入它們。然後內連線看起來像:

// do the inner join
var result = from f in first
             join s in second on f.ID equals s.ID
             select new { f.ID, s.RegionDescription };

 // Result: {1,"Eastern"}
 //         {3, Northern}  
 //         {4,"Southern"}  

這個結果動態建立了匿名物件,這很好,但我們已經建立了一個合適的類 - 所以我們可以指定它:我們可以說 select new { f.ID, s.RegionDescription }; 而不是 select new Region(f.ID, s.RegionDescription);,它會返回相同的資料,但會建立 Region 型別的物件 - 這將保持與其他物件的相容性。

.NET 小提琴的現場演示