[Lambda]Join

使用Lambda 實作 T-SQL的Inner Join 與 Left Outer Join

首先準備要實作的測試資料,(圖一)為測試資料的關係

[CUSTOMER]是存放顧客的資料表,包含姓名、證號等資料

[CARD]是存放卡片的資料表,包含對應是哪一個CUSTOMER、卡片號碼、發卡日期等資料(圖一)

當顧客領一張卡時,CARD就會新增一筆資料對應到CUSTOMER;反之未領卡的話,就不會有資料在CARD。

塞完資料後的清單請看(圖二)及(圖三)

(圖二)

(圖三)

資料準備好後,接著要來實作如何使用Lambda來實現Join。

Join最基本不外乎兩種:Inner JoinLeft 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長怎樣,維護性上也會降低,過了一陣子,連當時怎麼寫的也可能會看不懂。

 

參考資料:

 

創用 CC 授權條款
本著作由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.