免费A级毛片无码专区网站-成人国产精品视频一区二区-啊 日出水了 用力乖乖在线-国产黑色丝袜在线观看下-天天操美女夜夜操美女-日韩网站在线观看中文字幕-AV高清hd片XXX国产-亚洲av中文字字幕乱码综合-搬开女人下面使劲插视频

IQueryable和IEnumerable 快讀《ASP.NET Core技術(shù)內(nèi)幕與項(xiàng)目實(shí)戰(zhàn)》EFCore2.5:集合查詢?cè)斫颐?/h1>

本節(jié)內(nèi)容 , 涉及4.6(P116-P130) 。主要NuGet包:如前述章節(jié)
【IQueryable和IEnumerable 快讀《ASP.NET Core技術(shù)內(nèi)幕與項(xiàng)目實(shí)戰(zhàn)》EFCore2.5:集合查詢?cè)斫颐亍?/strong>一、LINQ和EFCore的集合查詢擴(kuò)展方法的區(qū)別
1、LINQ和EFCore中的集合查詢擴(kuò)展方法 , 雖然命名和使用完全一樣 , 都兩者定義在不同的命名空間下 , 是不同的方法 。PS:LINQ定義在System.Linq中 , EFCore定義在Microsoft.EntityFrameworkCore中
2、我們將集合操作的擴(kuò)展方法 , 劃分為兩類:①非立即執(zhí)行方法 , 如Where、OrderBy、Select、GroupBy、Skip、Take、Include等;②立即執(zhí)行方法:如Min、Max、Count、Sum、ToArray、ToList<T>、foreach等 。
3、當(dāng)執(zhí)行非立即方法時(shí) , LINQ返回IEnumerable集合 , EFCore返回IQueryable集合 。兩者最大區(qū)別為:LINQ會(huì)立即在服務(wù)器內(nèi)存中執(zhí)行計(jì)算(客戶端評(píng)估);而EFCore會(huì)延遲執(zhí)行 , 只有當(dāng)我們執(zhí)行立即執(zhí)行方法后 , EFCore才會(huì)將之前定義的所有非立即執(zhí)行方法 , 整合為SQL拋到數(shù)據(jù)庫執(zhí)行(服務(wù)端評(píng)估) 。
4、利用EFCore中IQueryable的特點(diǎn) , 我們就可以充分利用客戶端評(píng)估和服務(wù)端評(píng)估 , 達(dá)到延遲執(zhí)行、簡化代碼、復(fù)用代碼、平衡性能等目的
//LINQ返回IEnumerablevar nums = new int[] { 1, 2, 3, 4 };var numsNew = nums.Where(n => n > 2);//EFCore返回IQueryableusing var ctx = new MyDbContext();var books= ctx.Book.Where(a => a.Id > 0);二、IQueryable的延遲執(zhí)行案例
//利用IQueryable延遲執(zhí)行 , 拼接復(fù)雜查詢//定義一個(gè)復(fù)雜查詢的方法 , 接受參數(shù)①關(guān)鍵詞;②是否同時(shí)匹配書名和作者名;③是否按價(jià)格排序;④最高價(jià)格void QueryBooks(string searchWords, bool searchAll, bool orderByPrice, double upperPrice){using var ctx = new MyDbContext();//查詢低于最高價(jià)var books = ctx.Books.Where(b => b.Price <= upperPrice);//同時(shí)匹配書名和作者if(searchAll){books = books.Where(b => b.Title.Contains(searchWords) || b.AuthorName.Contains(searchWords));}//只匹配書名else{books = books.Where(b =>b.Title.Contains(searchWords));}//按照價(jià)格排序if(orderByPrice){books = books.OrderBy(b => b.Price);}//立即執(zhí)行方法 , 遍歷foreach(var item in books){Console.WriteLine($"書名:{item.Title} , 作者:{item.AuthorName}");}}//調(diào)用方法QueryBooks("LINQ", true, true, 30);//查詢書名或作者名 , 按價(jià)格排序QueryBooks("LINQ", false, false, 50); //只查詢書名 , 不按價(jià)格排序三、復(fù)用IQueryable的案例
//獲得一個(gè)IQueryable集合books , 并三次復(fù)用它var books = ctx.Books.Where(b => b.Price >=20);//使用books集合 , 執(zhí)行一次立即查詢Console.WriteLine(books.Count());//再次使用books集合 , 執(zhí)行第二次立即查詢Console.WriteLine(books.Max(b => b.Price));//第三次立即查詢foreach (var item in books.Where(b => b.PubTime.Year > 2000)){Console.WriteLine(item.Title);}四、結(jié)合使用服務(wù)端評(píng)估和客戶端評(píng)估的案例
//使用立即執(zhí)行方法ToList , 執(zhí)行SQL查詢(服務(wù)端評(píng)估) , 將結(jié)果存到服務(wù)器的內(nèi)存中var books = await ctx.Books.Take(100000).ToListAsync();//使用服務(wù)器內(nèi)存中的集合books , 進(jìn)行遍歷查詢 , 在服務(wù)器上執(zhí)行(客戶端評(píng)估)foreach (var item in books){Console.WriteLine(item.Title);}//由于遍歷條數(shù)比較多 , 需要一定時(shí)間//如果在遍歷過程中 , 我們關(guān)閉數(shù)據(jù)庫服務(wù)器 , 程序仍然可以正常進(jìn)行//說明遍歷前 , 已經(jīng)將數(shù)據(jù)下載到客戶端//大多數(shù)情況下 , 我們應(yīng)該復(fù)用IQueryable , 但在方法返回IQueryable , 或嵌套遍歷不同的DbSet時(shí) , 需要考慮特別注意//出錯(cuò)情況1:方法返回IQueryable//方法中返回IQueryable時(shí) , 會(huì)銷毀上下文//正確應(yīng)該返回:return ctx.Books.Where(b => b.Id>5).ToList();IQueryable<Book> QueryBooks(){using var ctx = MyDbContext();return ctx.Books.Where(b => b.Id>5);}foreach(var item in QueryBooks()){Console.WriteLine(item.Title);}//出錯(cuò)情況2:嵌套遍歷不同的DbSet//嵌套循環(huán) , 導(dǎo)致兩個(gè)DataReader執(zhí)行 , 大多數(shù)數(shù)據(jù)庫不允許多個(gè)DataReader同時(shí)執(zhí)行var books = ctx.Books.Where(b => b.Id > 1);foreach(var item1 in books){Console.WriteLine(item1.Title);foreach(var item2 in ctx.Authors){Console.WriteLive(item2.Id);}}

經(jīng)驗(yàn)總結(jié)擴(kuò)展閱讀