LINQ中的Join對應T-SQL中的 inner join, 並無Left Join的方法,當然也沒有Right Join。
要達成Left join 必須依靠GroupJoin來完成。
GroupJoin 顧名思義就是先Group 在做 Join ,與Join的不同處在於Join會得到一個一對一的新物件集合 (List<T>),而GroupJoin 則會得到一對多的物件集合({key,List<T>})。
以下是join 與GroupJoin的比較
var _Join = SLIST.Join(ScoreList, o => o.ID, p => p.StudentID, (o, c) => new { o.Classroom, o.ID,o.Name, c.Class,c.score });
var _GroupJoin = SLIST.GroupJoin(ScoreList, o => o.ID, p => p.StudentID, (o, c) => new { o.Classroom, o.ID, c });
//c只能以泛型物件的方式存入,不能列舉屬性
可以看GroupJoin 可以得到與Left Join相似的結果
接下來只要使用 SelectMany 將GroupJoin 中的內容展開
//將矩陣展開並輸出Null 得到left join資料集var _GroupJoinToLeftJoin = SLIST.GroupJoin(ScoreList, o => o.ID, p => p.StudentID, (o, c) => new { o.Classroom, o.ID,o.Name, c }).SelectMany(o => o.c.DefaultIfEmpty(), (o, c) => new { o.ID, o.Classroom,o.Name,Class=(c==null||c.Class==null?"N/A":c.Class), score= (c == null || c.score == null ? new Nullable<ushort>() : c.score) });//SelectMany 展開矩陣的內容//使用DefaultIfEmpty 因匿名型別無法輸出NULL(無法轉換成強型別),需特別注意Null的處理
查詢式的表示方法會比Lambda來的簡單一點
//查詢示 GroupJoin 寫法var _GroupJointoSQl=from o in SLISTjoin p in ScoreListon o.ID equals p.StudentIDinto groupjoin select groupjoin;//into 就是方法式中的 groupjoin
Left Join
var _LeftJointoSQl=from o in SLIST
join p in ScoreList
on o.ID equals p.StudentID
into groupjoin from a in groupjoin.DefaultIfEmpty()
select new{ o.ID, o.Classroom,o.Name,Class=(a==null||a.Class==null?"N/A":a.Class),
score= (a == null || a.score == null ? new Nullable<ushort>() : a.score)};
但是需注意,如果用 where 的方式做 join 的話會無法調用 DefaultIfEmpty()的方法
var Error = from o in SLISTfrom p in ScoreListwhere o.ID == p.StudentIDselect new { o.ID, o.Classroom, o.Name, p.Class, p.score }into sGroup from s in sGroup.DefaultIfEmpty() select sGroup;
因為使用where 後面必須接Select 語句輸出,但是select 後會成為匿名型別,無法再調用DefaultIfEmpty()