最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c# 動(dòng)態(tài)構(gòu)建LINQ查詢表達(dá)式

 更新時(shí)間:2020年11月27日 16:19:08   作者:精致碼農(nóng) • 王亮  
這篇文章主要介紹了c# 如何動(dòng)態(tài)構(gòu)建LINQ查詢表達(dá)式,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下

作者:精致碼農(nóng)

出處:http://cnblogs.com/willick

聯(lián)系:liam.wang@live.com

最近工作中遇到一個(gè)這樣的需求:在某個(gè)列表查詢功能中,可以選擇某個(gè)數(shù)字列(如商品單價(jià)、當(dāng)天銷售額、當(dāng)月銷售額等),再選擇 小于或等于大于或等于 ,再填寫一個(gè)待比較的數(shù)值,對(duì)數(shù)據(jù)進(jìn)行查詢過濾。

如果只有一兩個(gè)這樣的數(shù)字列,那么使用 Entity Framework Core 可以這么寫 LINQ 查詢:

public Task<List<Product>> GetProductsAsync(string propertyToFilter, MathOperator mathOperator, decimal value)
{
  var query = _context.Products.AsNoTracking();

  query = propertyToFilter switch
  {
    "Amount1" when mathOperator == MathOperator.LessThanOrEqual => query.Where(x => x.Amount1 <= value),
    "Amount1" when mathOperator == MathOperator.GreaterThanOrEqual => query.Where(x => x.Amount1 >= value),

    "Amount2" when mathOperator == MathOperator.LessThanOrEqual => query.Where(x => x.Amount2 <= value),
    "Amount2" when mathOperator == MathOperator.GreaterThanOrEqual => query.Where(x => x.Amount2 >= value),

    _ => throw new ArgumentException($"不支持 {propertyToFilter} 列作為數(shù)字列查詢", nameof(propertyToFilter))
  };

  return query.ToListAsync();
}

如果固定只有一兩個(gè)數(shù)字列且將來也不會(huì)再擴(kuò)展,這樣寫簡(jiǎn)單粗暴,也沒什么問題。

但如果有幾十個(gè)數(shù)字列,這樣使用 swith 模式匹配的寫法就太恐怖了,代碼大量重復(fù)。很自然地,我們得想辦法根據(jù)屬性名動(dòng)態(tài)創(chuàng)建 Where 方法的參數(shù)。它的參數(shù)類型是:Expression<Func<T, bool>>,是一個(gè)表達(dá)式參數(shù)。

要知道如何動(dòng)態(tài)創(chuàng)建一個(gè)類似 Expression<Func<T, bool>> 類型的表達(dá)式實(shí)例,就要知道如何拆解表達(dá)式樹。

對(duì)于本示例,以 x => x.Amount1 <= value 表達(dá)式實(shí)例為例,它的表達(dá)式樹是這樣的:

然后我們可以按照此表達(dá)式樹結(jié)構(gòu)來構(gòu)建我們的 LINQ 表達(dá)式:

public Task<List<Product>> GetProductsAsyncV2(string propertyToFilter, MathOperator mathOperator, decimal value)
{
  var query = _context.Products.AsNoTracking();

  var paramExp = Expression.Parameter(typeof(Product));
  var memberExp = Expression.PropertyOrField(paramExp, propertyToFilter);
  var valueExp = Expression.Constant(value);
  var compareExp = mathOperator == MathOperator.LessThanOrEqual ?
    Expression.LessThanOrEqual(memberExp, valueExp) :
    Expression.GreaterThanOrEqual(memberExp, valueExp);
  var lambda = Expression.Lambda<Func<Product, bool>>(compareExp, paramExp);

  return query.Where(lambda).ToListAsync();
}

每個(gè) Expression.XXX 靜態(tài)方法返回的都是一個(gè)以 Expression 為基類的實(shí)例,代表一個(gè)表達(dá)式。不同的表達(dá)式又可以組成一個(gè)新的表達(dá)式,直到得到我們需要的 Lambda 表達(dá)式。這樣就形成了一種樹形結(jié)構(gòu),我們稱為表達(dá)式樹。知道如何把一個(gè)最終的查詢表達(dá)式拆解成表達(dá)式樹,我們就容易動(dòng)態(tài)構(gòu)建此查詢表達(dá)式。

得到一個(gè)表達(dá)式后,我們還可以動(dòng)態(tài)編譯并調(diào)用該表達(dá)式,比如上面示例得到的 lambda 變量,是一個(gè)Expression<Func<Product, bool>> 類型,調(diào)用其 Compile 方法,可以得到 Func<Product, bool> 類型的委托。

...

var toTestProduct = new Product { Amount1 = 100, Amount2 = 200 };

Func<Product, bool> func = lambda.Compile();
var result = func(toTestProduct);

Console.WriteLine($"The product's {propertyToFilter} is to {mathOperator} {value}.");

// Output: The product's Amount1 is LessThanOrEqual to 150.

你可以通過研究 Expression 類來了解更多動(dòng)態(tài)構(gòu)建表達(dá)式的方法。

動(dòng)態(tài)構(gòu)建 LINQ 表達(dá)式對(duì)于不能在編譯時(shí)建立查詢,只能在運(yùn)行時(shí)建立查詢的場(chǎng)景很有用。但它的缺點(diǎn)也很明顯,不易維護(hù)、不易閱讀、不易調(diào)試。如果最終的表達(dá)式執(zhí)行出錯(cuò),很難通過調(diào)試來發(fā)現(xiàn)具體是構(gòu)建中的那一步寫錯(cuò)了,只能憑自己的理解和經(jīng)驗(yàn)查找錯(cuò)誤。所以,如非必須,一般不推薦動(dòng)態(tài)構(gòu)建 LINQ 查詢表達(dá)式。

以上就是c# 動(dòng)態(tài)構(gòu)建LINQ查詢表達(dá)式的詳細(xì)內(nèi)容,更多關(guān)于c# LINQ查詢表達(dá)式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C#/VB.NET實(shí)現(xiàn)HTML轉(zhuǎn)為XML的示例代碼

    C#/VB.NET實(shí)現(xiàn)HTML轉(zhuǎn)為XML的示例代碼

    可擴(kuò)展標(biāo)記語(yǔ)言(XML)文件是一種標(biāo)準(zhǔn)的文本文件,它使用特定的標(biāo)記來描述文檔的結(jié)構(gòu)以及其他特性。本文將利用C#實(shí)現(xiàn)HTML轉(zhuǎn)為XML,需要的可以參考一下
    2022-06-06
  • Unity 從UI中拖拽對(duì)象放置并拖動(dòng)效果 附demo

    Unity 從UI中拖拽對(duì)象放置并拖動(dòng)效果 附demo

    最近新接了個(gè)需求,要求模擬場(chǎng)景并生成3D對(duì)象,對(duì)象可以跟隨鼠標(biāo)移動(dòng)效果,今天小編把我實(shí)現(xiàn)的demo分享到腳本之家平臺(tái),對(duì)Unity UI拖拽相關(guān)知識(shí)感興趣的朋友跟隨小編一起學(xué)習(xí)吧
    2021-05-05
  • 詳解C#通過反射獲取對(duì)象的幾種方式比較

    詳解C#通過反射獲取對(duì)象的幾種方式比較

    本文主要介紹了C#通過反射獲取對(duì)象的幾種方式比較,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • C# 當(dāng)前系統(tǒng)時(shí)間獲取及時(shí)間格式詳解

    C# 當(dāng)前系統(tǒng)時(shí)間獲取及時(shí)間格式詳解

    這篇文章主要介紹了C# 當(dāng)前系統(tǒng)時(shí)間獲取及時(shí)間格式詳解的相關(guān)資料,這里提供代碼實(shí)例,幫助大家學(xué)習(xí)參考,需要的朋友可以參考下
    2016-12-12
  • C#之HttpClient設(shè)置cookies的兩種方式

    C#之HttpClient設(shè)置cookies的兩種方式

    這篇文章主要介紹了C#之HttpClient設(shè)置cookies的兩種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 深入淺析C#中的var和dynamic

    深入淺析C#中的var和dynamic

    這篇文章給大家介紹了C#中的var和dynamic的相關(guān)知識(shí),var和dynamic的本質(zhì)區(qū)別是類型判斷的時(shí)間不同,前者是編譯時(shí),后者是運(yùn)行時(shí)。具體內(nèi)容詳情大家通過本文學(xué)習(xí)下吧
    2018-05-05
  • C#中互操作性簡(jiǎn)介

    C#中互操作性簡(jiǎn)介

    這篇文章主要介紹了C#中互操作性的相關(guān)資料,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • C#中IEnumerable、ICollection、IList、List之間的區(qū)別

    C#中IEnumerable、ICollection、IList、List之間的區(qū)別

    IEnumerable、ICollection、IList、List之間的區(qū)別,本文分別分析了它的實(shí)現(xiàn)源碼,從而總結(jié)出了它們之間的關(guān)系和不同之處。對(duì)C# IEnumerable、ICollection、IList、List相關(guān)知識(shí),感興趣的朋友一起看看吧
    2021-07-07
  • 深入講解C#編程中嵌套類型和匿名類型的定義與使用

    深入講解C#編程中嵌套類型和匿名類型的定義與使用

    這篇文章主要介紹了C#編程中嵌套類型和匿名類型的定義與使用,包括在SQL語(yǔ)句中使用匿名類型的方法,需要的朋友可以參考下
    2016-01-01
  • linux操作系統(tǒng)安裝MONO執(zhí)行C#程序的詳解步驟

    linux操作系統(tǒng)安裝MONO執(zhí)行C#程序的詳解步驟

    這篇文章主要介紹了linux操作系統(tǒng)安裝MONO執(zhí)行C#程序詳解步驟,有需要的可以參考一下
    2013-12-12

最新評(píng)論

福州市| 仙桃市| 陇西县| 洞口县| 临西县| 招远市| 潜江市| 电白县| 大关县| 垣曲县| 湘阴县| 鲁甸县| 中宁县| 嘉义县| 台湾省| 塔河县| 正镶白旗| 德保县| 清原| 时尚| 滦南县| 迁安市| 太白县| 房产| 卢龙县| 巴楚县| 惠水县| 德安县| 方城县| 安庆市| 永清县| 安龙县| 临沭县| 裕民县| 平武县| 屏南县| 大城县| 马关县| 吉林市| 武定县| 兴城市|