欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

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

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

如果只有一兩個這樣的數(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();
}

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

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

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

對于本示例,以 x => x.Amount1 <= value 表達(dá)式實例為例,它的表達(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();
}

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

得到一個表達(dá)式后,我們還可以動態(tài)編譯并調(diào)用該表達(dá)式,比如上面示例得到的 lambda 變量,是一個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 類來了解更多動態(tài)構(gòu)建表達(dá)式的方法。

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

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

相關(guān)文章

  • C#索引器簡單實例代碼

    C#索引器簡單實例代碼

    打開.Net Framework源代碼隨便看幾個類,就會發(fā)現(xiàn)索引器的影子。索引器可以被重載,可以接收一個或者多個參數(shù),但是不可以定義為靜態(tài)的??梢杂藐P(guān)聯(lián)數(shù)組的方式訪問索引器。
    2013-03-03
  • C#中關(guān)于zip壓縮解壓幫助類的封裝 附源碼下載

    C#中關(guān)于zip壓縮解壓幫助類的封裝 附源碼下載

    之前一個同學(xué)問了這個問題后,看了園子里其它園友的封裝,都很零碎,調(diào)用也不是很方便。所以自己就封裝了一個zip解壓的類。后來想整理下怕自己忘了。就把壓縮的類也一并封裝了
    2013-02-02
  • C#實現(xiàn)簡易計算器功能(1)(窗體應(yīng)用)

    C#實現(xiàn)簡易計算器功能(1)(窗體應(yīng)用)

    這篇文章主要為大家詳細(xì)介紹了C#實現(xiàn)簡易計算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • c#使用windows服務(wù)更新站點地圖的詳細(xì)示例

    c#使用windows服務(wù)更新站點地圖的詳細(xì)示例

    這篇文章主要介紹了c#使用windows服務(wù)更新站點地圖的詳細(xì)示例,需要的朋友可以參考下
    2014-04-04
  • C#中如何把dll打包到exe

    C#中如何把dll打包到exe

    這篇文章主要介紹了C#中如何把dll打包到exe問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • C#實現(xiàn)類似新浪微博長URL轉(zhuǎn)短地址的方法

    C#實現(xiàn)類似新浪微博長URL轉(zhuǎn)短地址的方法

    這篇文章主要介紹了C#實現(xiàn)類似新浪微博長URL轉(zhuǎn)短地址的方法,涉及C#操作正則表達(dá)式的相關(guān)技巧,非常具有實用價值,需要的朋友可以參考下
    2015-04-04
  • 用C#縮小照片上傳到各種空間的具體方法

    用C#縮小照片上傳到各種空間的具體方法

    這篇文章介紹了用C#縮小照片的具體方法,有需要的朋友可以參考一下
    2013-09-09
  • c#?COM組件原理詳解

    c#?COM組件原理詳解

    本文主要介紹了c#?COM組件原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • C#中explicit與implicit的深入理解

    C#中explicit與implicit的深入理解

    這篇文章主要給大家介紹了關(guān)于C#中explicit與implicit的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • C#實現(xiàn)簡單播放mp3的方法

    C#實現(xiàn)簡單播放mp3的方法

    這篇文章主要介紹了C#實現(xiàn)簡單播放mp3的方法,涉及C#播放多媒體文件的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03

最新評論