C#如何動態(tài)創(chuàng)建lambda表達(dá)式
C#動態(tài)創(chuàng)建lambda表達(dá)式
近日在使用了一下EF框架,在做多條件where查詢的時候不知道怎么做,網(wǎng)上找了找,一開始用context.Database.SqlQuery<T>方法寫sql語句,之后遇到了SqlParamterCollection已在另一定義的問題,找了一下,大概知道什么問題,覺得用EF真的有點(diǎn)不方便,還不如用Dapper開發(fā)效率快,之后又在網(wǎng)上搜了搜關(guān)鍵字EF框架多條件Where查詢就打開了新世界的大門。
動態(tài)創(chuàng)建lambda表達(dá)式,我跟著學(xué)習(xí)了一下寫的
代碼如下:
? ? ? ? ? ?//querydata 是Dictionary<string,string> 放著要查詢的屬性名和相應(yīng)的值 ? ? ? ? ? ? ParameterExpression pe = Expression.Parameter(typeof(Customer), "customer");//lambda表示式里的參數(shù)我這邊是單參數(shù) ? ? ? ? ? ? Expression left;//相當(dāng)于 a=b 的 a ? ? ? ? ? ? Expression right;//相當(dāng)于a=b 的 b ? ? ? ? ? ? Expression e;//作為最后形成的表達(dá)式的載體 ? ? ? ? ? ? //先放一個初始值后面被替換不然循環(huán)里不方便用 ? ? ? ? ?? ? ? ? ? ? ? left = Expression.Property(pe, typeof(Customer).GetProperty("name"));//Customer.name ? ? ? ? ? ? right = Expression.Constant("巔峰白楊");//Constant方法設(shè)置屬性對應(yīng)的值 ? ? ? ? ? ? e = Expression.Equal(left, right);//Customer.name=="巔峰白楊" ? ? ? ? ? ? //循環(huán)查詢條件字典 ? ? ? ? ? ? ?foreach (var item in querydata) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? if (!item.Value.ToString().Trim().Equals("")) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? left = Expression.Property(pe, typeof(SFC_Package).GetProperty(item.Key)); ? ? ? ? ? ? ? ? ? ? right = Expression.Constant(item.Value); ? ? ? ? ? ? ? ? ? ? if (index == 0) ? ? ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? e = Expression.Equal(left, right); ? ? ? ? ? ? ? ? ? ? ? ? index++; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? else ? ? ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? if (e != null) ? ? ? ? ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? ? ? Expression tempe; ? ? ? ? ? ? ? ? ? ? ? ? ? ? tempe = Expression.Equal(left, right); ? ? ? ? ? ? ? ? ? ? ? ? ? ? e = Expression.And(tempe, e);//加了一個&&連接兩個判斷 ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ?? ? ? ? ? ? ? IQueryable<Customer> queryableData = db.Customer.AsQueryable<Customer>();//將IEnumerable類型轉(zhuǎn)成IQueryable ? ? ? ? ?? ? ? ? ? ? ? //Where方法的lambda表達(dá)式 ? ? ? ? ? ? MethodCallExpression whereCallExpression = Expression.Call( ? ? ? ? ? ? typeof(Queryable), ? ? ? ? ? ? "Where", ? ? ? ? ? ? new Type[] { queryableData.ElementType }, ? ? ? ? ? ? queryableData.Expression, ? ? ? ? ? ? Expression.Lambda<Func<SFC_Package, bool>>(e, new ParameterExpression[] { pe })); ? ? ? ? ? ? //OrderBy方法的lambda表達(dá)式 這邊寫的有點(diǎn)冗余第一次寫不太習(xí)慣,想想重復(fù)了很多 ? ? ? ? ? ? var propertyinfo=typeof(Customer).GetProperty("Name"); ? ? ? ? ? ? Expression body=Expression.Property(pe,propertyinfo); ? ? ? ? ? ? Type nametype=propertyinfo.PropertyType; ? ? ? ? ? ? MethodCallExpression orderByCallExpression = Expression.Call( ? ? ? ? ? ? ?typeof(Queryable), ? ? ? ? ? ? "OrderBy", ? ? ? ? ? ? new Type[] { queryableData.ElementType, nametype},//其實(shí)可以寫成queryableData.ElementType.GetProperty("Name").PropertyType ? ? ? ? ? ? ? ? ? ? ? ? whereCallExpression, ? ? ? ? ? ? Expression.Lambda(body, pe)); ? ? ? ? ? ? //使用已創(chuàng)建好的lambda表達(dá)式查詢數(shù)據(jù) ps:IQueryable和IEnumerable可以轉(zhuǎn)換方便處理查詢結(jié)果 ? ? ? ? ? ? ?IQueryable<SFC_Package> results = queryableData.Provider.CreateQuery<Customer>(orderByCallExpression);
網(wǎng)上還看到一種簡單的多條件查詢的方法,相當(dāng)于
var data=db.Customer.Where(o=>o.name=="西門吹雪"); data=data.Where(o=>o.sex="男神")
用循環(huán)來多次Where實(shí)現(xiàn)多條件查詢,感覺可能會造成多次數(shù)據(jù)庫查詢,不過用在Linq to Object
上應(yīng)該挺好的。
最后學(xué)習(xí)的動態(tài)創(chuàng)建lambda表達(dá)式地址 點(diǎn)擊打開鏈接
Lambda表達(dá)式動態(tài)拼接生成工具類
public static class LambdaUtil<T> { /// <summary> /// lambda表達(dá)式:t=>true /// </summary> /// <returns></returns> public static Expression<Func<T, bool>> True() { return t => true; } /// <summary> /// lambda表達(dá)式:t=>false /// </summary> /// <returns></returns> public static Expression<Func<T, bool>> False() { return t => false; } /// <summary> /// lambda表達(dá)式:t=>t.propName /// 多用于order排序 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <typeparam name="TKey">返回類型</typeparam> /// <param name="propName">屬性名</param> /// <returns></returns> private static Expression<Func<T, TKey>> Order<TKey>(string propName) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // 創(chuàng)建一個屬性 MemberExpression property = Expression.Property(parameter, propName); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, TKey>>(property, parameter); } /// <summary> /// lambda表達(dá)式:t=>t.propName==propValue /// 多用于where條件 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <param name="propName">屬性名稱</param> /// <param name="propValue">屬性值</param> /// <returns></returns> public static Expression<Func<T, bool>> Equal(string propName, object propValue) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // 創(chuàng)建一個成員(字段/屬性) MemberExpression member = Expression.PropertyOrField(parameter, propName); // 創(chuàng)建一個常數(shù) ConstantExpression constant = Expression.Constant(propValue); // 創(chuàng)建一個相等比較Expression BinaryExpression binary = Expression.Equal(member, constant); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(binary, parameter); } /// <summary> /// lambda表達(dá)式:t=>t.propName!=propValue /// 多用于where條件 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <param name="propName">屬性名稱</param> /// <param name="propValue">屬性值</param> /// <returns></returns> public static Expression<Func<T, bool>> NotEqual(string propName, object propValue) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // 創(chuàng)建一個成員(字段/屬性) MemberExpression member = Expression.PropertyOrField(parameter, propName); // 創(chuàng)建一個常數(shù) ConstantExpression constant = Expression.Constant(propValue); // 創(chuàng)建一個不相等比較Expression BinaryExpression binary = Expression.NotEqual(member, constant); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(binary, parameter); } /// <summary> /// lambda表達(dá)式:t=>t.propName<propValue /// 多用于where條件 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <param name="propName">屬性名稱</param> /// <param name="propValue">屬性值</param> /// <returns></returns> public static Expression<Func<T, bool>> LessThan(string propName, object propValue) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // 創(chuàng)建一個成員(字段/屬性) MemberExpression member = Expression.PropertyOrField(parameter, propName); // 創(chuàng)建一個常數(shù) ConstantExpression constant = Expression.Constant(propValue); // 創(chuàng)建一個不相等比較Expression BinaryExpression binary = Expression.LessThan(member, constant); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(binary, parameter); } /// <summary> /// lambda表達(dá)式:t=>t.propName<=propValue /// 多用于where條件 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <param name="propName">屬性名稱</param> /// <param name="propValue">屬性值</param> /// <returns></returns> public static Expression<Func<T, bool>> LessThanOrEqual(string propName, object propValue) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // 創(chuàng)建一個成員(字段/屬性) MemberExpression member = Expression.PropertyOrField(parameter, propName); // 創(chuàng)建一個常數(shù) ConstantExpression constant = Expression.Constant(propValue); // 創(chuàng)建一個不相等比較Expression BinaryExpression binary = Expression.LessThanOrEqual(member, constant); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(binary, parameter); } /// <summary> /// lambda表達(dá)式:t=>t.propName>propValue /// 多用于where條件 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <param name="propName">屬性名稱</param> /// <param name="propValue">屬性值</param> /// <returns></returns> public static Expression<Func<T, bool>> GreaterThan(string propName, object propValue) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // 創(chuàng)建一個成員(字段/屬性) MemberExpression member = Expression.PropertyOrField(parameter, propName); // 創(chuàng)建一個常數(shù) ConstantExpression constant = Expression.Constant(propValue); // 創(chuàng)建一個不相等比較Expression BinaryExpression binary = Expression.GreaterThan(member, constant); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(binary, parameter); } /// <summary> /// lambda表達(dá)式:t=>t.propName>=propValue /// 多用于where條件 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <param name="propName">屬性名稱</param> /// <param name="propValue">屬性值</param> /// <returns></returns> public static Expression<Func<T, bool>> GreaterThanOrEqual(string propName, object propValue) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // 創(chuàng)建一個成員(字段/屬性) MemberExpression member = Expression.PropertyOrField(parameter, propName); // 創(chuàng)建一個常數(shù) ConstantExpression constant = Expression.Constant(propValue); // 創(chuàng)建一個不相等比較Expression BinaryExpression binary = Expression.GreaterThanOrEqual(member, constant); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(binary, parameter); } /// <summary> /// lambda表達(dá)式:t=>{t.contains(propvalue1) ||...||t.contains(propvalueN)} /// 多用于where條件 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <param name="propName">屬性名稱</param> /// <param name="propValues">屬性值數(shù)組</param> /// <returns></returns> public static Expression<Func<T, bool>> In(string propName, string[] propValues) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // left // 創(chuàng)建一個成員(字段/屬性) MemberExpression member = Expression.PropertyOrField(parameter, propName); // 創(chuàng)建一個常數(shù) Expression constant = Expression.Constant(false); // 創(chuàng)建一個方法 MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); foreach (string item in propValues) { // 創(chuàng)建一個帶參數(shù)方法Expression MethodCallExpression methodCall = Expression.Call(member, method, Expression.Constant(item)); // right // 連接參數(shù)方法 constant = Expression.Or(methodCall, constant); } // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(constant, new ParameterExpression[] { parameter }); } /// <summary> /// lambda表達(dá)式:t=>{!(t.contains(propvalue1) ||...||t.contains(propvalueN))} /// 多用于where條件 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <param name="propName">屬性名稱</param> /// <param name="propValues">屬性值數(shù)組</param> /// <returns></returns> public static Expression<Func<T, bool>> NotIn(string propName, string[] propValues) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // 創(chuàng)建一個成員(字段/屬性) MemberExpression member = Expression.PropertyOrField(parameter, propName); // 創(chuàng)建一個常數(shù) Expression constant = Expression.Constant(false); // 創(chuàng)建一個方法 MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); foreach (string item in propValues) { // 創(chuàng)建一個帶參數(shù)方法Expression MethodCallExpression methodCall = Expression.Call(member, method, Expression.Constant(item)); // right // 連接參數(shù)方法 constant = Expression.Or(methodCall, constant); } // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(Expression.Not(constant), new ParameterExpression[] { parameter }); } /// <summary> /// lambda表達(dá)式:t=>t.propName.Contains(propValue) /// 多用于where條件 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <param name="propName">屬性名稱</param> /// <param name="propValue">屬性值</param> /// <returns></returns> public static Expression<Func<T, bool>> Contains(string propName, string propValue) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // 創(chuàng)建一個成員(字段/屬性) MemberExpression member = Expression.PropertyOrField(parameter, propName); // 創(chuàng)建一個常數(shù) ConstantExpression constant = Expression.Constant(propValue, typeof(string)); // 創(chuàng)建一個方法 MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); // 創(chuàng)建一個帶參數(shù)方法Expression MethodCallExpression methodCall = Expression.Call(member, method, constant); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(methodCall, parameter); } /// <summary> /// lambda表達(dá)式:t=>t.propName.Contains(propValue) /// 多用于where條件 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <param name="propName">屬性名稱</param> /// <param name="propValue">屬性值</param> /// <returns></returns> public static Expression<Func<T, bool>> StartWith(string propName, string propValue) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // 創(chuàng)建一個成員(字段/屬性) MemberExpression member = Expression.PropertyOrField(parameter, propName); // 創(chuàng)建一個常數(shù) ConstantExpression constant = Expression.Constant(propValue, typeof(string)); // 創(chuàng)建一個方法 MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) }); // 創(chuàng)建一個帶參數(shù)方法Expression MethodCallExpression methodCall = Expression.Call(member, method, constant); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(methodCall, parameter); } /// <summary> /// lambda表達(dá)式:t=>t.propName.Contains(propValue) /// 多用于where條件 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <param name="propName">屬性名稱</param> /// <param name="propValue">屬性值</param> /// <returns></returns> public static Expression<Func<T, bool>> EndsWith(string propName, string propValue) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // 創(chuàng)建一個成員(字段/屬性) MemberExpression member = Expression.PropertyOrField(parameter, propName); // 創(chuàng)建一個常數(shù) ConstantExpression constant = Expression.Constant(propValue, typeof(string)); // 創(chuàng)建一個方法 MethodInfo method = typeof(string).GetMethod("EndsWith", new[] { typeof(string) }); // 創(chuàng)建一個帶參數(shù)方法Expression MethodCallExpression methodCall = Expression.Call(member, method, constant); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(methodCall, parameter); } /// <summary> /// lambda表達(dá)式:!(t=>t.propName.Contains(propValue)) /// 多用于where條件 /// </summary> /// <typeparam name="T">參數(shù)類型</typeparam> /// <param name="propName">屬性名稱</param> /// <param name="propValue">屬性值</param> /// <returns></returns> public static Expression<Func<T, bool>> NotContains(string propName, string propValue) { // 創(chuàng)建節(jié)點(diǎn)參數(shù)t ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // 創(chuàng)建一個成員(字段/屬性) MemberExpression member = Expression.PropertyOrField(parameter, propName); // 創(chuàng)建一個常數(shù) ConstantExpression constant = Expression.Constant(propValue, typeof(string)); // 創(chuàng)建一個方法 MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); // 創(chuàng)建一個帶參數(shù)方法Expression MethodCallExpression methodCall = Expression.Call(member, method, constant); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(Expression.Not(methodCall), parameter); } /// <summary> /// lambda表達(dá)式:t=>{left and right} /// 多用于where條件 /// </summary> /// <param name="left">左側(cè)條件</param> /// <param name="right">右側(cè)條件</param> /// <returns></returns> public static Expression<Func<T, bool>> And(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right) { // 創(chuàng)建參數(shù)表達(dá)式 InvocationExpression invocation = Expression.Invoke(right, left.Parameters.Cast<Expression>()); // 創(chuàng)建and運(yùn)算 BinaryExpression binary = Expression.And(left.Body, invocation); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(binary, left.Parameters); } /// <summary> /// lambda表達(dá)式:t=>{left or right} /// 多用于where條件 /// </summary> /// <param name="left">左側(cè)條件</param> /// <param name="right">右側(cè)條件</param> /// <returns></returns> public static Expression<Func<T, bool>> Or(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right) { // 創(chuàng)建參數(shù)表達(dá)式 InvocationExpression invocation = Expression.Invoke(right, left.Parameters.Cast<Expression>()); // 創(chuàng)建or運(yùn)算 BinaryExpression binary = Expression.Or(left.Body, invocation); // 生成lambda表達(dá)式 return Expression.Lambda<Func<T, bool>>(binary, left.Parameters); } }
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
C# WinForm實(shí)現(xiàn)Win7 Aero透明效果代碼
這篇文章主要介紹了C# WinForm實(shí)現(xiàn)Win7 Aero透明效果代碼,通過調(diào)用dwmapi.dll相關(guān)方法實(shí)現(xiàn),需要的朋友可以參考下2014-07-07WPF+Canvas實(shí)現(xiàn)平滑筆跡的示例代碼
這篇文章主要介紹了如何利用WPF+Canvas實(shí)現(xiàn)平滑筆跡效果,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定幫助,需要的可以參考一下2022-09-09