日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

IEnumerableT和IQueryableT区分

發(fā)布時(shí)間:2023/12/13 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IEnumerableT和IQueryableT区分 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

哎,看了那么多,這個(gè)知識(shí)點(diǎn)還是得開一個(gè)文章

IQueryable和IEnumerable都是延時(shí)執(zhí)行(Deferred Execution)的,而IList是即時(shí)執(zhí)行(Eager Execution)

IQueryable和IEnumerable在每次執(zhí)行時(shí)都必須連接數(shù)據(jù)庫讀取,而IList讀取一次后,以后各次都不需連接數(shù)據(jù)庫。

前兩者很容易造成重復(fù)讀取,性能低下,并且可能引發(fā)數(shù)據(jù)不一致性

IQueryable弊端:當(dāng)把查詢出來的數(shù)據(jù),根據(jù)指定條件添加到其他表中時(shí),會(huì)報(bào)連接以打開錯(cuò)誤!原因:IQueryable在每次執(zhí)行時(shí)都必須連接數(shù)據(jù)庫讀取,所以數(shù)據(jù)庫連接是一直開著的!

?

LINQ查詢方法一共提供了兩類擴(kuò)展方法,在System.Linq命名空間下,有兩個(gè)靜態(tài)類:

    Enumerable類,它針對(duì)繼承了IEnumerable<T>接口的集合類進(jìn)行擴(kuò)展。

    Queryable類,它針對(duì)繼承了IQueryable<T>接口的集合類進(jìn)行擴(kuò)展。

接口IQueryable<T>實(shí)際也是繼承了IEnumerable<T>接口的,簡(jiǎn)單的來表述就是:本地?cái)?shù)據(jù)源用IEnumerable<T>,遠(yuǎn)程數(shù)據(jù)源用IQueryable<T>。

LINQ查詢從功能上來講實(shí)際上可以分為三類:LINQ to OBJECTS、LINQ to ?SQL、LINQ to XML。設(shè)計(jì)Enumerable<T>和Queryable<T>兩套接口的原因是為了區(qū)別對(duì)待LINQ to OBJECTS、LINQ to SQL,

針對(duì)LINQ to OBJECTS時(shí),使用Enumerable中的擴(kuò)展方法對(duì)本地集合進(jìn)行排序和查詢等操作,查詢參數(shù)接受的是Func<>。

針對(duì)LINQ to SQL時(shí),則使用Queryable中的擴(kuò)展方法,它接受的參數(shù)是Expression<>。

LINQ to SQL引擎最終會(huì)將表達(dá)式樹轉(zhuǎn)化成為相應(yīng)的SQL語句,然后在數(shù)據(jù)庫中執(zhí)行。//表達(dá)式樹???啥jb

?

原文
在使用EF查詢數(shù)據(jù)的時(shí)候,我們常用的查詢數(shù)據(jù)方式有l(wèi)inq to sql,linq to object,
查詢返回的結(jié)果有兩種類型:IQueryable、IEnumerable,兩者內(nèi)部的處理機(jī)制是完全不同的。
在System.linq命名空間,有兩個(gè)靜態(tài)類:Queryable和Enumerable.

在System.linq.Queryable中,參數(shù)接收的是一個(gè)表達(dá)式類型,返回IQueryable接口
public?static?IQueryable<TSource>?Where<TSource>(this?IQueryable<TSource>?source,?Expression<Func<TSource,?bool>>?predicate);
在System.linq.Enumerable中,參數(shù)接收的是一個(gè)謂詞表達(dá)式,也就是一個(gè)委托
public?static?IEnumerable<TSource>?Where<TSource>(this?IEnumerable<TSource>?source,?Func<TSource,?bool>?predicate);?? 那么在查詢數(shù)據(jù)使用linq to object的時(shí)候,會(huì)根據(jù)傳遞的參數(shù)不同返回不同的類型.?
1.where條件接收表達(dá)式,返回IQueryable接口

2.where條件接收一個(gè)謂詞表達(dá)式(委托)返回一個(gè)IEnumerable接口

那么什么時(shí)候用IQueryable<T>,什么時(shí)候用IEnumerable<T>?

1.Expression是一個(gè)表達(dá)式,會(huì)存儲(chǔ)拼接表達(dá)式樹,直到在運(yùn)行期最終執(zhí)行。

2.Func<>謂詞表達(dá)式,就是一個(gè)委托,委托一旦調(diào)用,就立即執(zhí)行了,將執(zhí)行結(jié)果保存在內(nèi)存中。

那么在EF中我們根據(jù)條件查詢數(shù)據(jù)時(shí),不應(yīng)該把數(shù)據(jù)一次性加載到本地內(nèi)存中,然后再本地內(nèi)存中進(jìn)行篩選,如果數(shù)據(jù)量大了,就崩潰了。

我們需要將表達(dá)式組合好,然后再一起提交到數(shù)據(jù)庫執(zhí)行,返回查詢結(jié)果。(那這句話的意思是在ef查詢中用Iqueryable接收)

每次在執(zhí)行where查詢操作符的時(shí)候IQueryProvider會(huì)為我們創(chuàng)建一個(gè)新的IQueryable<T>,調(diào)用AsEnumerable()方法的時(shí)候并不會(huì)去實(shí)際取值,只是

得到了一個(gè)IEnumerable,所以EF在查詢數(shù)據(jù)時(shí)候不要先取IEnumerable再去篩選數(shù)據(jù)。執(zhí)行ToList方法時(shí)才會(huì)去真正調(diào)用迭代器GetEnumerator()
取值。真正取值時(shí)候,會(huì)去執(zhí)行IQueryProvider中的Excute方法.(解析表達(dá)式,然后執(zhí)行取得結(jié)果))

這就是IQueryable的延遲加載把.

原文

  

轉(zhuǎn)載于:https://www.cnblogs.com/ZkbFighting/p/9142646.html

總結(jié)

以上是生活随笔為你收集整理的IEnumerableT和IQueryableT区分的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。