使用Lambda 實作 T-SQL的Inner Join 與 Left Outer Join
首先準備要實作的測試資料,(圖一)為測試資料的關係
[CUSTOMER]是存放顧客的資料表,包含姓名、證號等資料
[CARD]是存放卡片的資料表,包含對應是哪一個CUSTOMER、卡片號碼、發卡日期等資料(圖一)
當顧客領一張卡時,CARD就會新增一筆資料對應到CUSTOMER;反之未領卡的話,就不會有資料在CARD。
塞完資料後的清單請看(圖二)及(圖三)
(圖二)
(圖三)
資料準備好後,接著要來實作如何使用Lambda來實現Join。
Join最基本不外乎兩種:Inner Join & Left Outer Join
Inner Join
我想要取得有哪些顧客有領卡片,沒領過卡片不需要知道
var innerJoin_Data = db.CUSTOMER.Join(
db.CARD, //要Join的資料表
c => c.CUSTOMER_ID, //c代表db.CUSTOMER(c可以自己定義名稱),這邊放主要資料表要串聯的key
cd => cd.CUSTOMER_ID, //cd代表db.CARD(cd可以自己定義名稱),這邊放次資料表要串聯的key
(c, cd) => new //將兩個自定義名稱用小括胡包起來,接著透過 『=>』 可以自己選擇要取用要用資料
{
name = c.NAME,
cradNbr = cd.CARD_NUMBER
}
).ToList();
Console.WriteLine("Result\r\n---------------------------");
foreach (var item in innerJoin_Data)
{
Console.WriteLine("{0}\t已領卡號:{1}", item.name, item.cradNbr);
}
結果如(圖四),在Entity Framework 6 ,可以透過db.Database.log將轉成T-SQL語法輸出,如(圖四)紅框部份,而藍框部分就是我們最後輸出的結果。
(圖四)
Left Outer Join
我想要取得有多少顧客,有領卡片的帶出卡號,沒領過卡片不用帶出卡號
var LeftJoin_Data = db.CUSTOMER.SelectMany //使用SelectMany
(c => db.CARD.Where(cd => cd.CUSTOMER_ID == c.CUSTOMER_ID).DefaultIfEmpty(),//要Left Outer Join的方式,若沒有就預設值
(c, cd) => new {
name = c.NAME,
cardNbr = cd.CARD_NUMBER
}).ToList();
Console.WriteLine("Result\r\n---------------------------");
foreach (var item in LeftJoin_Data)
{
Console.WriteLine("{0}\t已領卡號:{1}", item.name, item.cardNbr ?? "");
}
結果如(圖五),在藍框部分就是我們最後輸出的結果。
(圖五)
總結:
學會之後,其實發現Join也不是很難,不過還是要有一個觀念,若是要串聯非常多的資料表的話,建議還是使用Stored Procedure(預存程序)或是View(檢視表)來取得資料。
否則串再多,最後自己還是不確定底層幫你轉出的SQL長怎樣,維護性上也會降低,過了一陣子,連當時怎麼寫的也可能會看不懂。
參考資料:
本著作由Chenting Weng製作,以創用CC 姓名標示 4.0 國際 授權條款釋出。
This work by Chenting Weng is licensed under a Creative Commons Attribution 4.0 International License.
Based on a work at https://dotblogs.com.tw/chentingw.
部分文章內容會引用到其他網站的簡介或圖片,若有侵犯到您的著作權,請留言告知,本人會儘快移除。
免責聲明:文章屬個人記事使用,僅供參考,若引用文章造成一切損失,本人不承擔任何責任。如有錯誤,歡迎留言告知。
Part of the content of the article will refer to the profile or picture of other websites.
If there is any infringement of your copyright, please leave a message and let me remove it as soon as possible.
Disclaimer:The article is for personal use and is for reference only. I will not bear any responsibility for any loss caused by quoting the article. If there is an error, please leave a message to inform.