1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        IQueryable 和 IEnumerable 的區(qū)別

        共 1912字,需瀏覽 4分鐘

         ·

        2022-07-13 19:12

        推薦關(guān)注「碼俠江湖」星標(biāo),時(shí)刻不忘江湖事

        這是 EF Core 系列的最后一篇文章,按照上一篇的計(jì)劃,我們最后就講一講 IQueryable 和 IEnumerable 的區(qū)別。

        點(diǎn)擊上方或后方藍(lán)字,閱讀 EF Core 系列合集。

        在前面的一些例子中,我們會(huì)在使用 LINQ 查詢(xún)方法之后,又使用 ToList 等方法,將查詢(xún)結(jié)果轉(zhuǎn)換成集合。

        如果我們不使用 ToList 呢?

        比如這個(gè)示例:

        using var context = new BloggingContext();
        var posts = context.Posts.OrderBy(p => p.BlogId == 1).ToList();
        var posts1 = context.Posts.OrderBy(p => p.BlogId == 1);

        這里有兩個(gè)查詢(xún),一個(gè)使用了 ToList 方法,另一個(gè)沒(méi)有。

        執(zhí)行這段代碼,在控制臺(tái)中查看日志:

        可以看到只有一條 SQL 語(yǔ)句被執(zhí)行,按理說(shuō)我們有兩個(gè) LINQ 查詢(xún),應(yīng)該有兩條 SQL 語(yǔ)句,但是只有一條,這是為什么?

        其實(shí),我們調(diào)用的 LINQ 查詢(xún)方法,本身是不會(huì)執(zhí)行查詢(xún)操作的。

        簡(jiǎn)單來(lái)說(shuō),我們執(zhí)行的 LINQ 方法,只是轉(zhuǎn)換成了查詢(xún)表達(dá)式,被存儲(chǔ)在了 IQueryable 類(lèi)型的對(duì)象中。

        只有當(dāng)我們需要數(shù)據(jù)的時(shí)候,比如當(dāng)我們使用 ToList 方法時(shí),EF Core 才會(huì)將整個(gè)出啊訊表達(dá)式,翻譯成 SQL 語(yǔ)句執(zhí)行。

        這種需要數(shù)據(jù)時(shí)才會(huì)查詢(xún)的行為,看起來(lái)有點(diǎn)像顯式加載,但絕對(duì)不是一回事兒。

        結(jié)合示例簡(jiǎn)單的說(shuō),「post1」 只是一個(gè)以 LINQ 表達(dá)式體現(xiàn)的查詢(xún)語(yǔ)句,就好比你編寫(xiě)了一條字符串 SQL 語(yǔ)句。

        至于這條語(yǔ)句是否執(zhí)行,取決于下一步操作。比如 ToList 方法,就是這一步查詢(xún)操作。

        因?yàn)槭褂?ToList 方法的目的,就是為了獲取數(shù)據(jù)集合,所以 EF Core 才會(huì)執(zhí)行這條查詢(xún)語(yǔ)句。

        如果非要給這種行為起一個(gè)名字的話,我覺(jué)得應(yīng)該叫延遲執(zhí)行更合適。

        我們?cè)賮?lái)看看,LINQ 方法返回的數(shù)據(jù)類(lèi)型是什么:

        「post1」 的數(shù)據(jù)類(lèi)型是泛型的 IOrderedQueryable,它本質(zhì)上是就是一個(gè) IQueryable 類(lèi)型,不過(guò)是具有排序表達(dá)式的 IQueryable。

        LINQ 方法往往都有好幾個(gè)重載,比如 OrdeyByWhere 等方法,它們返回的數(shù)據(jù)類(lèi)型有兩種:IQueryableIEnumerable

        那么這兩種數(shù)據(jù)類(lèi)型究竟有何區(qū)別?我們做個(gè)試驗(yàn):

        在這個(gè)示例中,「posts」「posts1」 的語(yǔ)句,可以視為等效的。

        這是因?yàn)椴樵?xún)參數(shù)會(huì)被默認(rèn)為 IQueryable 類(lèi)型,所以最終使用的還是返回 IQueryable 類(lèi)型的重載方法。

        在 post2 的語(yǔ)句中,由于 IQueryable 繼承了 IEnumerable,所以可以通過(guò) AsEnumerable 方法,將其返回值轉(zhuǎn)換為 IEnumerable 類(lèi)型。

        在這種情況下,只有當(dāng)代碼運(yùn)行到兩個(gè) foreach 遍歷的時(shí)候,才會(huì)真正的執(zhí)行語(yǔ)句。

        接下來(lái),再看這個(gè)示例:

        這個(gè)示例與前面一個(gè)示例的不同之處在于,「posts1」 查詢(xún)語(yǔ)句的 LINQ 方法在 AsEnumerable 之后才調(diào)用。

        運(yùn)行程序,觀察控制臺(tái)日志:

        此時(shí)我們終于發(fā)現(xiàn)了不同,兩條 SQL 語(yǔ)句不同,第一條 SQL 語(yǔ)句比第二條 SQL 語(yǔ)句多了一個(gè)分頁(yè)操作。

        IQueryable 在查詢(xún)的時(shí)候,會(huì)應(yīng)用所有 LINQ 方法,并且生成一個(gè)完整的 SQL 查詢(xún)語(yǔ)句,去數(shù)據(jù)庫(kù)執(zhí)行并獲取符合查詢(xún)語(yǔ)句的數(shù)據(jù);

        而當(dāng)我們使用 IEnumerable 時(shí),則會(huì)生成一條將所有的數(shù)據(jù)查詢(xún)出來(lái)的 SQL 語(yǔ)句,而后在內(nèi)存中再對(duì)數(shù)據(jù)進(jìn)行處理,最終獲得符合查詢(xún)語(yǔ)句的數(shù)據(jù)。

        在不使用 AsEnumerable 的情況下,默認(rèn)都是采用 IQueryable 進(jìn)行查詢(xún)。

        那么我們什么時(shí)候應(yīng)該使用 AsEnumerable ?

        使用 「AsEnumerable」 的查詢(xún),稱(chēng)為客戶(hù)端查詢(xún)。

        比如,當(dāng)你想在客戶(hù)端完成篩選或者聚合等操作的時(shí)候,可以選擇轉(zhuǎn)換成 IEnumerable 進(jìn)行查詢(xún)。

        雖然這增大了數(shù)據(jù)庫(kù)查詢(xún)壓力和IO壓力,但因?yàn)閷⒂?jì)算轉(zhuǎn)移到了客戶(hù)端,所以也相應(yīng)的減輕了數(shù)據(jù)庫(kù)的計(jì)算壓力。

        簡(jiǎn)單來(lái)說(shuō)是,這是一種用 I/O 資源換計(jì)算資源的行為。


        瀏覽 44
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            懂色av浪潮av色欲av熟妇 | 亚洲AV无码成人精品区麻豆 | 很黄很色的性过程详细描写的故事 | 青青草人人操 | av中文字幕在线观看 | 大焦煮伊人| 成人免费黄色大片 | 欧美色图第三页 | 黄色视频免费在线播放 | 91成人视频在线观看 |