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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

c# 经验谈:巧用Expression表达式 解决类似于sql中 select in 的查询(适合于中小型项目)...

發布時間:2025/5/22 C# 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c# 经验谈:巧用Expression表达式 解决类似于sql中 select in 的查询(适合于中小型项目)... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們在項目經常會碰到一些特殊需求 例如下拉框是復選的,查詢條件是根據下拉框中復選項進行拼接

看到此圖后大家肯定會說,這很簡單嘛

將所有的選項 拼成“'1-3','5-9'”? 然后放到 in 的字句后面,一查就出來了。

這樣做的確在邏輯上沒有問題,可是大家有沒有想過這個問題,過度的和業務耦合雖然能夠解決

現在的需求但是卻犧牲了代碼優雅和可維護性

?

其實本文的目的是想利用Expression表達式在linq查詢中實現一個優雅的解決方案,

同時也會給大家一個用Expression去拼接sql的思路

?

先上代碼

public static Expression<Func<T, bool>> GetConditionExpression<T>(string[] options, string fieldName)
{
ParameterExpression left = Expression.Parameter(typeof(T), "c");//c=>
Expression expression = Expression.Constant(false);
foreach (var optionName in options)
{
Expression right = Expression.Call
(
Expression.Property(left, typeof(T).GetProperty(fieldName)), //c.DataSourceName
typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),// 反射使用.Contains()方法 s Expression.Constant(optionName) // .Contains(optionName)
);
expression = Expression.Or(right, expression);//c.DataSourceName.contain("") || c.DataSourceName.contain("")
}
Expression<Func<T, bool>> finalExpression
= Expression.Lambda<Func<T, bool>>(expression, new ParameterExpression[] { left });
return finalExpression;
}

我想用逆推的方式說明下這段代碼,其實我們查詢的目的要實現這樣的效果 , someList.where(c=>c.Name.contains("someName")||c.Name.Contains("someName")||...)

1. 首先我們要確定返回什么樣的表達式,根據經驗.where后面是需要一個Expression<Func<T, bool>> 這樣的一個表達式,所以方法的返回類型已經能確定下來了

2. 接下來的任務是拼接類似于c=>c.Name.Contains("") 這樣的表達式,按照自左向右的原則,左側表達式參數c很好理解 就是T,那么這個表達式的參數也就搞定了,

可以用Expression.Parameter方法來實現,該方法目的是將類型反射并且映射給表達式中的匿名變量 “c” (也可以理解成將參數常量封裝成表達式)

3. 接著是表達式右側的拼接

?再次仔細看下這段代碼

Expression right = Expression.Call?

?(??????????????????????????

???? Expression.Property(left, typeof(T).GetProperty(fieldName)),? //c.DataSourceName?????首先是反射獲取c的一個屬性????????????????

???? typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),// 聲明一個string.Contains的方法?????c.DataSourceName.Contains()????????????????反射使用.Contains()方法??

???? Expression.Constant(optionName)?????????? // ?c.DataSourceName.Contains(optionName)???????????????封裝常量???????

?);

? 為什么要使用Expression.Call ?

(因為c.Name.contains 屬于string.contains()這個方法所以我們必須將該方法封裝成表達式,Expression.Call的功能就是將方法封裝成表達式

?這時候大家會問contains什么呢? 當然常量option雖然是string類型,但是仍需封裝成表達式,Expression.Constant(optionName) 起到了封裝常量的作用

?于是c=>c.屬性.Contains(常量) 這個表達式搞定,可是還是有問題:怎么加上“||” ,聰明的你已經有了答案,Expression.Or()

?

4 最后一步當然非常關鍵,就像產品需要通過流水線進行包裝組合,表達式也不例外:

Expression.Lambda<Func<T, bool>>(expression, new ParameterExpression[] { left });

對于整個表達式來說,左側是參數表達式(ParameterExpression),Expression.Lambda就是=>符號,就右側表達式和參數表達式通過lambda符號進行組合,搞定

?

這樣的話,你只需傳入一個字符串數組就能在Linq中實現類似于sql中select in 的效果了,

很多朋友肯定會問,既然能夠用自定義表達式搞定,那么可不可以將表達式的思路用于拼接sql?

答案是肯定的。但是如果業務邏輯非常復雜,而且難以把握,還是建議用ado?配合存過實現

?

?

感謝女友一直陪到深夜,讓我堅持把這篇博文寫完,文中如有錯誤,也請大家海涵并且能夠及時告訴我,謝謝!

?

?

?

?

?

?

?

?

?

?

?

?

轉載于:https://www.cnblogs.com/JimmyZheng/archive/2012/02/23/2364154.html

總結

以上是生活随笔為你收集整理的c# 经验谈:巧用Expression表达式 解决类似于sql中 select in 的查询(适合于中小型项目)...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。