使用linq語句進行聯表查詢


假設你有一個父表(例如:汽車),其關聯一個子表,例如輪子(一對多)。現在你想對於所有的父表汽車,遍歷所有汽車,然后打印出來所有輪子的信息。默認的做法將是:

SELECT CarId FROM Cars;

然后對於每個汽車:

SELECT * FROM Wheel WHERE CarId = ?

這會SELECT 2個表一共N(主表的行數)+1(父表)次,故稱為SELECT N+1問題。

考察下面的代碼。假設ProvinceMeeting是一個會議表,MeetSign是另外一個會議簽到表,ProvinceMeeting和MeetSign是一對多的關系:

不推薦的寫法

                        var Ids = container.ProvinceMeeting.Select(f => f.Id).ToList();
                        var SignEntities = container.MeetingSign.ToList();
                        foreach (var Id in Ids)
                        {
                            var sign = container.MeetingSign.Where(f => f.MeetingId == Id);
                        }

每次循環都會連接數據庫,執行一條sql語句,select N + 1問題,很消耗性能。

改善后的寫法:

                       //這是我曾經的寫法,先遍歷獲取主表和所有的子表數據存儲在數組中,然后再foreach循環查詢取出每個主表對應的子表信息, 
                        var Entities = container.ProvinceMeeting.ToList();
                        var SignEntities = container.MeetingSign.ToList();
                        foreach (var item in Entities)
                        {
                            var sign = SignEntities.Where(f => f.MeetingId == item.Id);
                        }

我們知道foreach會強制LINQ執行,於是,我們可以想象這也是一個SELECT N+1問題的例子:先獲得所有ProvinceMeeting(SELECT * FROM ProvinceMeeting),然后遍歷,再去SELECT 表MeetingSign,共SELECT N+1次。(當然這里我把數據都啦取出來,儲存在內存中,進行操作相當也查詢了兩次,但隨后我還要遍歷循環操作數組)。

 

解決方法:使用一個匿名對象作為中間表格,預先將兩個表join到一起

最佳寫法:

var  results = container.ProvinceMeeting.Select(f => new { f.Id, son = f.MeetingSign });

我們對結果添加監聽,執行效果如下:

主表和子表對應的關聯數據,綁定在了一起,不止代碼簡單,執行效率也高出了不少!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM