用Join來做資料聯集,在T-SQL指令是常會用到的一種語法,不過,對於常寫SQL語法的人要轉換到Linq語法時,往往對於Join這語句的操作就常會感到比較陌生也不習慣要怎樣使用。因此,這邊簡單說明一下,要如何操作Linq的join語法
資料表A
資料表B
Join
先來做兩個資料的Join,把資料表B去顯示對應的資料表A的WeekName,Join是算是Linq比較簡單易懂的,其條件為透過資料表A的Week與資料表B的WeekSQL這兩個欄位相等之關係之資料集
1 2 3 4 5
| from ss in Config_WeekMappings join aa in S_Student_Curriculums on new { WeekID=ss.Week} equals new {WeekID=aa.WeekSQL} select new { WeekSQL=ss.Week,WeekName=ss.WeekName,week=aa.Week}
|
跟我們熟悉的SQL語法是相同的
1 2 3
| SELECT [t0].[Week] AS [WeekSQL], [t0].[WeekName] FROM [Config_WeekMapping] AS [t0] INNER JOIN [S_Student_Curriculum] AS [t1] ON [t0].[Week] = [t1].[WeekSQL]
|
若是要這Joine過程中去過濾一些資料呢?例如我只要取資料表A中的Week等於1的資料,其語法如下:
1 2 3 4 5 6
| from ss in Config_WeekMappings join aa in S_Student_Curriculums on new { WeekID=ss.Week} equals new {WeekID=aa.WeekSQL} where ss.Week==1 select new { WeekSQL=ss.Week,WeekName=ss.WeekName}
|
而除了一個過濾條件外,我們又想在資料表B中取出某一個學號且WeekSQL為1的資料,其語法如下:
1 2 3 4 5 6
| from ss in Config_WeekMappings join aa in S_Student_Curriculums on new { WeekID=ss.Week} equals new {WeekID=aa.WeekSQL} where aa.S_Num=="S20142001" && ss.Week==1 select new { WeekSQL=ss.Week,WeekName=ss.WeekName}
|
這樣就可以採用兩個條件做篩選,且可以分別篩選出不同資料表的條件。因此,即使在Linq中也可以很輕鬆的透過這樣語法做過濾條件,Linq轉成SQL語句是跟我們再用SQL指令的方式是相同的。
Right Join
使用Right Join在Linq中並無真正去區分Right Join或是Left Join的關鍵字。這一點跟SQL指令不太一樣,在SQL中還可以採用Right Join & Left Join去指定資料表的聯集方式。但是,在Linq這邊語法就沒有這樣直覺,Linq語法中都只有Join這指令而已,因此,先來講Right Join作法,後面再接著說Left Join,個人認為right Join比較需要換個方向思考才能與SQL相同
想要把資料表A去Right Join資料表B,其SQL語法可以這樣下:
1 2 3 4 5 6 7 8
| SELECT [t0].[Week] AS [WeekSQL] , [t0].[WeekName] , t1.Week FROM [dbo].[Config_WeekMapping] [t0] RIGHT JOIN ( SELECT WeekSQL , Week FROM [dbo].[S_Student_Curriculum] ) t1 ON t0.Week = t1.WeekSQL
|
在Linq並無Right Join語法,因此,我做法則是把資料表兩個做對調,其意義為用資料表B去Left Join資料表A,這樣就可以達到資料表A做Right Join資料表B的功能,其與法如下:
1 2 3 4 5 6
| from ss in S_Student_Curriculums join aa in Config_WeekMappings on new { WeekID=ss.WeekSQL} equals new {WeekID=aa.Week} into temp from ds in temp.DefaultIfEmpty() select new { WeekSQL=ds.Week,WeekName=ds.WeekName,week=ss.Week}
|
而當我們在Linq語法中,無論是right join或是left Join中,要取得第一個資料表S_Student_Curriculums的欄位,直接使用上述的變數ss指向欄位即可,但是,若是要取得第二個資料表欄位Config_WeekMappings,則不是直接取用變數aa對應欄位,而是必須使用temp這個變數去對映相關欄位才可以,因此,上面語法對照的SQL語法如下:
1 2 3
| SELECT [t1].[Week] AS [WeekSQL], [t1].[WeekName] AS [WeekName], [t0].[Week] AS [week] FROM [S_Student_Curriculum] AS [t0] LEFT OUTER JOIN [Config_WeekMapping] AS [t1] ON [t0].[WeekSQL] = [t1].[Week]
|
若是這邊要做一些資料篩檢的話,就跟Join方式的是相同的概念,下面篩選案例與Join中的案例相同,其語句如下:
1 2 3 4 5 6 7
| from ss in S_Student_Curriculums join aa in Config_WeekMappings on new { WeekID=ss.WeekSQL} equals new {WeekID=aa.Week} into temp from ds in temp.DefaultIfEmpty() where ss.S_Num=="S20142001" && ds.Week==3 select new { WeekSQL=ds.Week,WeekName=ds.WeekName,week=ss.Week}
|
Left Join
資料表A做left Join資料表B其語法如下,這部份跟right join是相同的,就把剛剛資料表B再與資料表A做對調即可
1 2 3 4 5 6
| from ss in Config_WeekMappings join aa in S_Student_Curriculums on new { WeekID=ss.Week} equals new {WeekID=aa.WeekSQL} into temp from ds in temp.DefaultIfEmpty() select new { WeekSQL=ss.Week,WeekName=ss.WeekName,week=ds.Week}
|
當然這邊SQL語法也是跟right join是相同的,只有資料表對調而已
以上就是針對Linq做Join系列的簡單作法,不過,上述案例只有針對一個條件做Join,也就是on A.XX=B.XX,若是要針對兩個欄位進行Join呢?只要針對下圖的紅框部分,依序加入欄位就可以。