<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      追根溯源之Linq與表達式樹

      一、什么是表達式樹?

      ??首先來看下官方定義(以下摘錄自巨硬官方文檔)

      ??表達式樹表示樹狀數據結構中的代碼,其中每個節點都是表達式,例如,方法調用或諸如的二進制操作x < y。
      ??您可以編譯和運行由表達式樹表示的代碼。這樣就可以對可執行代碼進行動態修改,在各種數據庫中執行LINQ查詢以及創建動態查詢。有關LINQ中的表達式樹的更多信息,請參見如何使用表達式樹構建動態查詢(C#)。
      ??在動態語言運行時(DLR)中還使用了表達式樹,以提供動態語言和.NET之間的互操作性,并使編譯器編寫程序可以發出表達式樹而不是Microsoft中間語言(MSIL)。有關DLR的更多信息,請參見《動態語言運行時概述》。
      ??您可以讓C?;騐isual Basic編譯器根據匿名lambda表達式為您創建一個表達式樹,或者您可以使用System.Linq.Expressions命名空間手動創建表達式樹。

      ??從上面我們可以提取一些關鍵信息——它是一種樹型結構、表達式樹可以被編譯成可執行代碼然后運行、DLR使用了表達式樹、可以用表達式樹來達到和直接寫MSIL一樣的效果、C#編譯器能夠根據匿名Lambda表達式靜態生成構建表達式樹的代碼、你可以手動編寫構建表達式樹的代碼。
      ??其實第一個關鍵信息就是表達式樹的全部,后面的所有功能都是在這之上衍生出來的,所以用我的話來回答,什么是表達式樹?表達式樹就是一種樹形數據結構,在這個結構上包含了代碼邏輯所必須的信息,用這些信息我們可以用來做很多事,例如,生成MSIL代碼,生成SQL語句等等,這也是Linq To Anything的基礎。

      二、Linq

      ??Linq(語言集成查詢),在.Neter中經常用到的技術,你雖然在開發中經常用到,但你有沒有了解過到它到底是怎么運作的呢?我們來扒一扒。

      1.Linq To Entity

      ??首先,Linq的鏈式調用,是靠擴展方法實現的,Linq主要擴展了IEnumerable<T>IQueryable<T>兩大接口。我們看下針對IEnumerable<T>的擴展。

      public static class Enumerable
      {
          //所有針對IEnumerable<TSource>的擴展方法
          public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
          //省略......
      }
      
      

      ??觀察可以發現,針對IEnumerable的擴展方法,貌似跟Expression沒有半毛錢關系。是的,半分錢關系都沒有。這樣做其實是為了性能考慮,因為這些查詢實際上是從MSIL翻譯成機器代碼本地執行,我何必要先解析表達式樹,然后翻譯成MSIL,再到機器代碼呢?這也是所謂的Linq To Entity

      2.Linq To Other

      ??對IQueryable<T>的擴展如下:

      public static class Queryable
      {
          //所有針對IEnumerable<TSource>的擴展方法
          public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate)
          //省略......
      }
      

      ??觀察可以發現,在Where擴展方法中有一個Expression<Func<TSource, bool>>類型的參數。這就是一個表達式樹,確切的說是一個Lambda表達式樹,這個Lamdbda表達式樹包含了必要的信息,在對source上調用了這個方法,并傳入一個Lambda表達式樹之后,source內部會被把傳入的表達式樹添加到之前的表達式樹節點上,然后返回一個新的IQueryable<TSource>實例,其中內部的表達式樹已經包含了你剛傳入的表達式節點,然后你可以在此之上繼續調用擴展方法,當在調用諸如First()、ToList()、Count()等之類的方法之后,將會導致內部的表達式樹被一個解析器解析,然后根據解析出來的結果,去查數據庫、去檢索JSON文件、去檢索XML文件或是調用外部服務等,最后生成數據到內存,構造成一個List實例給你。至于內部的細節到底是什么,有時間再寫。

      3.問題

      ??細心的朋友可能注意到,上節提到的一個Expression<Func<TSource, bool>>類型的參數,這個是怎么構造出來的呢?我們平時開發的時候好像從沒有構造過啊。其實文章開頭就有提到,

      ??您可以讓C?;騐isual Basic編譯器根據匿名lambda表達式為您創建一個表達式樹,或者您可以使用System.Linq.Expressions命名空間手動創建表達式樹。

      ??發現沒,這個臟活其實是由編譯器幫我們干了,我們來驗證一下。新建.Net Core控制臺程序如下:

          static void Main(string[] args)
          {
              List<int> datas = new List<int> { 1, 2, 3, 4, 5, 6 };
              var res = datas.AsQueryable().Where(x => x > 3).ToList();
          }
      

      ??使用Debug模式編譯,然后用一個你喜歡的反編譯工具(PS:反編譯一般指把中間語言代碼變成高級語言代碼,而反匯編一般指把機器代碼變成匯編語言代碼)反編譯生成的程序集,這里我使用的是DNSPY。
      如果使用的是DNSPY,記得把“反編譯表達式樹”選項關掉。
      ??內容如下:

      // Token: 0x02000002 RID: 2
      internal class Program
      {
          // Token: 0x06000001 RID: 1 RVA: 0x00002050 File Offset: 0x00000250
          private static void Main(string[] args)
          {
              List<int> datas = new List<int>
              {
                  1,
                  2,
                  3,
                  4,
                  5,
                  6
              };
              IQueryable<int> source = datas.AsQueryable<int>();
              ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "x");
              List<int> res = source.Where(Expression.Lambda<Func<int, bool>>(Expression.GreaterThan(parameterExpression, Expression.Constant(3, typeof(int))), new ParameterExpression[]
              {
                  parameterExpression
              })).ToList<int>();
          }
      }
      

      ??可以發現,編譯器幫我們把Lambda表達式編譯成了表達式樹。

      三、總結

      ??總的來說,表達式樹是Linq中不可或缺的一環,為了方便人們使用表達式樹,編譯器也做了許多工作,從而避免用戶手動構造表達式樹,因此選用了Lambda表達式這種用戶熟悉的形式給用戶使用,但同時,也提高了理解門檻。

      四、題外話

      ??為了減少重復勞動,我編寫了一個動態構建查詢的類庫,基于.NetStandard,支持靜態排序,動態排序,多重排序,模糊查詢,分頁查詢,能適用大多數的后臺管理應用開發場景。原理其實就是動態構建表達式樹。GitHub上有文檔,Nuget上搜索EazyPageQuery,記得勾選“包括預發行版”~

      NuGet Badge
      Github:https://github.com/HekunX/EazyPageQuery

      posted @ 2020-11-02 18:57  白煙染黑墨  閱讀(858)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 亚洲男人AV天堂午夜在| 无码专区 人妻系列 在线| 免费观看欧美猛交视频黑人| 忘忧草www日本韩国| 朝阳区| 天堂资源在线| 亚洲一区二区av观看| 99精品伊人久久久大香线蕉| 亚洲色婷婷综合开心网| 亚洲无人区一区二区三区| 亚洲av无一区二区三区| 亚洲一区精品视频在线| 中文字幕亚洲人妻系列| 狠狠色婷婷久久综合频道日韩 | 人妻中文字幕亚洲精品| аⅴ天堂国产最新版在线中文| 色婷婷久久综合中文久久一本 | 国内精品免费久久久久电影院97| 国产综合久久久久久鬼色| 亚洲精品日本一区二区| 国产一区国产精品自拍| 日本一区二区三区免费播放视频站| 久久久综合香蕉尹人综合网| 国产精品麻豆va在线播放| 国产午夜亚洲精品福利| 大地资源网第二页免费观看| 精品国产欧美一区二区三区在线| 无码综合天天久久综合网 | 国产精品午夜福利精品| 欧洲性开放老太大| 农村熟女大胆露脸自拍| 吉水县| 老司机精品影院一区二区三区| 国产99在线 | 免费| 太仆寺旗| 国产成人一区二区三区在线| 91福利视频一区二区| 茄子视频国产在线观看| 亚洲综合色网一区二区三区| 国产精品SM捆绑调教视频| 狂野欧美性猛交免费视频|