EF架構~linq模擬left join的兩種寫法,性(xing)能差(cha)之千里!
對于SQL左外連接(jie)(jie)我想沒什么可(ke)說(shuo)的(de)(de),left join將左表(biao)數據都獲出來(lai),右表(biao)數據如果(guo)在左表(biao)中不(bu)存(cun)在,結果(guo)為NULL,而(er)對于LINQ來(lai)說(shuo),要(yao)實現left join的(de)(de)效果(guo),也是(shi)可(ke)以的(de)(de),在進行join時直(zhi)接(jie)(jie)into到(dao)集合變(bian)量就可(ke)以了,但在賦值時,如果(guo)只需要(yao)集合的(de)(de)一條記(ji)錄,那在寫法(fa)上又會(hui)有(you)兩(liang)種,而(er)這(zhe)兩(liang)種寫法(fa)所產生的(de)(de)性能(neng)是(shi)相關千里的(de)(de),下(xia)面來(lai)看一下(xia).
首先是(shi)SQL的左外連(lian)接
SELECT [t6].[CourseID] , [t6].[UserID] , [t6].[CourseName] , [t6].[ResourceID] , [t6].[StudyTime] , [t6].[BeginTime] , [t6].[EndTime] , [t6].[value] AS [CategoryID] , [t6].[value2] AS [ClassHour] , [t6].[value3] AS [Percent] , [t6].[test] , [t6].[ID] , [t6].[SmallPicture] FROM dbo.User_Course AS t6 LEFT OUTER JOIN [User_StudyRecord] AS t3 ON t6.UserID = t3.UserID AND t3.ResourceID = t6.ResourceID
當它被翻譯(yi)成(cheng)LINQ之后,是(shi)分頁產生(sheng)的結(jie)果,所以感(gan)覺更很亂了,呵(he)呵(he),(LINQ在翻譯(yi)SQL時,本來就夠亂的,再一分頁,用(yong)上(shang)row_number,更亂了),但結(jie)果是(shi)一樣的,
咱們就不(bu)管微(wei)軟是怎么翻譯(yi)的(de)了(le)
我們重要是看一(yi)下(xia),實現時LINQ代碼的寫法
第一種(zhong),性能低下的,如果(guo)結果(guo)為20條記錄,那它需(xu)要多連接20次
var linq = from _data in new User_Course(UnitOfWork).GetEntities() let list = new Res_Item(UnitOfWork).GetEntities().Select(t => new Entity.Res_Item { ID = t.ID, SmallPicture = t.SmallPicture, }).Where(i => i.ID == _data.ResourceID) let list2 = new User_StudyRecord(UnitOfWork).GetModel().Select(r => new Entity.User_StudyRecord { StudyContent = r.StudyContent, UserID = r.UserID, Res_ItemID = r.Res_ItemID, }).Where(i => i.Res_ItemID == _data.ResourceID && i.UserID == _data.UserID) from record in list2.DefaultIfEmpty() where _data.CategoryID != (int)CustomEnum.CategoryType.BroadcastProgram && _data.CategoryID != (int)CustomEnum.CategoryType.AskRoom select new Entity.User_Course { CourseID = _data.CourseID, UserID = _data.UserID, CourseName = _data.CourseName, ResourceID = _data.ResourceID, StudyTime = _data.StudyTime, BeginTime = _data.BeginTime, EndTime = _data.EndTime, CategoryID = _data.CategoryID ?? 2, Res_Item = list.FirstOrDefault(), ClassHour = _data.ClassHour ?? 0, Percent = _data.Percent ?? 0, Prev_ResourceName = record == null ? string.Empty : record.StudyContent, };
第二種,性能較好的
總(zong)結:對于(yu)(yu)第一(yi)種性能較差的寫法產生的結果,類似于(yu)(yu)LINQ本身提交(jiao)的延時(shi)加載(zai),即結果集中(zhong),每條記錄都去查(cha)詢數(shu)(shu)據(ju)庫,它不(bu)會(hui)一(yi)次(ci)將(jiang)數(shu)(shu)據(ju)獲出來(lai),這種作用在(zai)特定場合是
有(you)它的好處的,但不適(shi)用(yong)于所有(you),當返(fan)回結果集(ji)比較大時,不應該使用(yong)延時加載(zai)!