基于网上找的一段代码进行修改,目前扩展了NotContains方法的实现

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ZW.CateringSystem.Common.ConvertHelper; namespace ZW.CateringSystem.Common.LinqHelper
{
#region 动态linq帮助类,连接符号,运算符号 /// <summary>
/// 动态linq工厂
/// </summary>
public static class DynamicLinqFactory
{ /// <summary>
/// 生成lambd表达式
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="propertyStr"></param>
/// <returns></returns>
public static Expression<Func<TSource, bool>> CreateLambda<TSource>(string propertyStr)
{
// 设置自定义lanbd
// 定义 lanbd 种子(p=> xxxxxx)中的 p
var parameter = Expression.Parameter(typeof(TSource), "p");
var strArr = SpiltStrings(propertyStr); // 第一个判断条件,固定一个判断条件作为最左边
Expression mainExpressin = ExpressionStudio(null, strArr.FirstOrDefault(x => x.LinkSymbol == LinkSymbol.Empty), parameter); // 将需要放置在最左边的判断条件从列表中去除,因为已经合成到表达式最左边了
strArr.Remove(strArr.FirstOrDefault(x => x.LinkSymbol == LinkSymbol.Empty)); foreach (var x in strArr)
{
mainExpressin = ExpressionStudio(mainExpressin, x, parameter);
} return mainExpressin.ToLambda<Func<TSource, bool>>(parameter);
} /// <summary>
/// 组合条件判断表达式
/// </summary>
/// <param name="left">左边的表达式</param>
/// <param name="DynamicLinq"></param>
/// <param name="key"></param>
/// <returns></returns>
public static Expression ExpressionStudio(Expression left, DynamicLinqHelper DynamicLinq, ParameterExpression key)
{
Expression mainExpression = key; var properties = DynamicLinq.Left.Split('.'); // 从1开始,是不想用自定义种子,外层种子已经定义好了
// 暂时也不会有多个自定义种子,先这样
for (var i = ; i < properties.Length; i++)
{
mainExpression = mainExpression.Property(properties[i]);
} left = left == null
// 如果左边表达式为空,则当前的表达式就为最左边
? ChangeOperationSymbol(DynamicLinq.OperationSymbol, mainExpression, DynamicLinq.Right)
// 如果不为空,则将当前的表达式连接到左边
: ChangeLinkSymbol(DynamicLinq.LinkSymbol, left, ChangeOperationSymbol(DynamicLinq.OperationSymbol, mainExpression, DynamicLinq.Right));
return left;
} /// <summary>
/// 将字符串装换成动态帮助类(内含递归)
/// </summary>
public static List<DynamicLinqHelper> SpiltStrings(string propertyStr)
{
// 定义返回用List
var outList = new List<DynamicLinqHelper>(); // 当最后已经没有连接运算符的时候,进入该条件
if (!propertyStr.Contains("&") & !propertyStr.Contains("|"))
{
// 当前的条件是不具备连接符号的
var lastStr = propertyStr.Trim().Split(' ');
if (lastStr.Length == )
{
outList.Add(new DynamicLinqHelper
{
LinkSymbol = LinkSymbol.Empty,
Left = lastStr[],
Right = "",
OperationSymbol = ChangeOperationSymbol("null")
});
return outList;
}
outList.Add(new DynamicLinqHelper
{
LinkSymbol = LinkSymbol.Empty,
Left = lastStr[],
Right = lastStr[],
OperationSymbol = ChangeOperationSymbol(lastStr[])
});
return outList;
}
// 判断当前 & | 哪个符号在最后一个判断逻辑内
var key = propertyStr.LastIndexOf('&') > propertyStr.LastIndexOf('|') ? '&' : '|'; var nowStrArr = propertyStr.Substring(propertyStr.LastIndexOf(key)).Trim().Split(' '); outList.Add(new DynamicLinqHelper
{
LinkSymbol = ChangeLinkSymbol(nowStrArr[]),
Left = nowStrArr[],
OperationSymbol = ChangeOperationSymbol(nowStrArr[]),
Right = nowStrArr[]
});
// 将剩余部分继续切割
propertyStr = propertyStr.Substring(, propertyStr.LastIndexOf(key)).Trim();
// 递归 由后彺前
outList.AddRange(SpiltStrings(propertyStr)); return outList;
} /// <summary>
/// 将字符串符号转成运算枚举符号
/// </summary>
public static LinkSymbol ChangeLinkSymbol(string str)
{
// 这里判断链接符号
// 当链接符号为Empty,则说明当前对象为表达式的最左边
// 如果一个表达式出现两次链接符号为空,则说明输入的字符串格式有问题
switch (str)
{
case "|":
return LinkSymbol.OrElse;
case "&":
return LinkSymbol.AndAlso;
default:
return LinkSymbol.Empty;
}
} /// <summary>
/// 将运算枚举符号转成具体使用方法
/// </summary>
public static Expression ChangeLinkSymbol(LinkSymbol Symbol, Expression left, Expression right)
{
switch (Symbol)
{
case LinkSymbol.OrElse:
return left.OrElse(right);
case LinkSymbol.AndAlso:
return left.AndAlso(right);
default:
return left;
}
} /// <summary>
/// 将字符串符号转成运算枚举符号
/// </summary>
public static OperationSymbol ChangeOperationSymbol(string str)
{
switch (str)
{
case "<":
return OperationSymbol.LessThan;
case "<=":
return OperationSymbol.LessThanOrEqual;
case ">":
return OperationSymbol.GreaterThan;
case ">=":
return OperationSymbol.GreaterThanOrEqual;
case "==":
return OperationSymbol.Equal;
case "!=":
return OperationSymbol.NotEqual;
case "Contains":
return OperationSymbol.Contains;
case "NotContains":
return OperationSymbol.NotContains;
case "null":
return OperationSymbol.Null;
}
throw new Exception("OperationSymbol IS NULL");
} /// <summary>
/// 将运算枚举符号转成具体使用方法
/// </summary>
public static Expression ChangeOperationSymbol(OperationSymbol symbol, Expression key, object right)
{
if (symbol == OperationSymbol.Null)
{
return key;
}
// 将右边数据类型强行转换成左边一样的类型
// 两者如果Type不匹配则无法接下去的运算操作,抛出异常
object newTypeRight;
if (right.ToString() == "null")
{ newTypeRight = null; }
else
{
//判断key.Type的类型,调用不同的方法进行转换;
var t = key.Type;
newTypeRight = ConvertionExtensions.ChangeType(right, key.Type);
} // 根据当前枚举类别判断使用那种比较方法
switch (symbol)
{
case OperationSymbol.Equal:
return key.Equal(Expression.Constant(newTypeRight));
case OperationSymbol.GreaterThan:
return key.GreaterThan(Expression.Constant((newTypeRight)));
case OperationSymbol.GreaterThanOrEqual:
return key.GreaterThanOrEqual(Expression.Constant(newTypeRight));
case OperationSymbol.LessThan:
return key.LessThan(Expression.Constant((newTypeRight)));
case OperationSymbol.LessThanOrEqual:
return key.LessThanOrEqual(Expression.Constant((newTypeRight)));
case OperationSymbol.NotEqual:
return key.NotEqual(Expression.Constant(newTypeRight));
case OperationSymbol.Contains:
return key.Contains(Expression.Constant(newTypeRight));
case OperationSymbol.NotContains: // 不包含
return Expression.Not(key.Contains(Expression.Constant(newTypeRight)));
}
throw new Exception("OperationSymbol IS NULL");
}
} /// <summary>
/// 动态linq帮助类
/// </summary>
public class DynamicLinqHelper
{
[Display(Name = "左")]
public string Left { get; set; }
[Display(Name = "右")]
public string Right { get; set; } [Display(Name = "运算符")]
public OperationSymbol OperationSymbol { get; set; } [Display(Name = "连接符")]
public LinkSymbol LinkSymbol { get; set; }
} /// <summary>
/// 连接符枚举(将来可能会包含 括号 )
/// </summary>
public enum LinkSymbol
{
[Display(Name = "&&")]
AndAlso,
[Display(Name = "||")]
OrElse,
[Display(Name = "空")]
Empty
} /// <summary>
/// 常用比较运算符 > , >= , == , < , <= , != ,Contains
/// </summary>
public enum OperationSymbol
{
[Display(Name = "Contains")]
Contains,
[Display(Name = "NotContains")]
NotContains,
[Display(Name = ">")]
GreaterThan,
[Display(Name = ">=")]
GreaterThanOrEqual,
[Display(Name = "<")]
LessThan,
[Display(Name = "<=")]
LessThanOrEqual,
[Display(Name = "==")]
Equal,
[Display(Name = "!=")]
NotEqual,
[Display(Name = "null")]
Null
} #endregion /// <summary>
/// Linq扩展
/// </summary>
public static class ExpressionExtensions
{
#region 常用扩展方法 /// <summary>
/// 调用内部方法
/// </summary>
public static Expression Call(this Expression instance, string methodName, params Expression[] arguments)
{
return Expression.Call(instance, instance.Type.GetMethod(methodName), arguments);
} /// <summary>
/// 获取内部成员
/// </summary>
public static Expression Property(this Expression expression, string propertyName)
{
// Todo:左边条件如果是dynamic,
// 则Expression.Property无法获取子内容
// 报错在这里,由于expression内的对象为Object,所以无法解析到
// var x = (expression as IQueryable).ElementType;
return Expression.Property(expression, propertyName);
} /// <summary>
/// 转Lambda
/// </summary>
public static Expression<TDelegate> ToLambda<TDelegate>(this Expression body,
params ParameterExpression[] parameters)
{
return Expression.Lambda<TDelegate>(body, parameters);
} #endregion #region 常用运算符 [ > , >= , == , < , <= , != , || , && ] /// <summary>
/// &&
/// </summary>
public static Expression AndAlso(this Expression left, Expression right)
{
return Expression.AndAlso(left, right);
} /// <summary>
/// ||
/// </summary>
public static Expression OrElse(this Expression left, Expression right)
{
return Expression.OrElse(left, right);
} /// <summary>
/// Contains
/// </summary>
public static Expression Contains(this Expression left, Expression right)
{
return left.Call("Contains", right);
} /// <summary>
/// >
/// </summary>
public static Expression GreaterThan(this Expression left, Expression right)
{
return Expression.GreaterThan(left, right);
} /// <summary>
/// >=
/// </summary>
public static Expression GreaterThanOrEqual(this Expression left, Expression right)
{
return Expression.GreaterThanOrEqual(left, right);
} /// <summary>
/// <
/// </summary>
public static Expression LessThan(this Expression left, Expression right)
{
return Expression.LessThan(left, right);
} /// <summary>
/// <=
/// </summary>
public static Expression LessThanOrEqual(this Expression left, Expression right)
{
return Expression.LessThanOrEqual(left, right);
} /// <summary>
/// ==
/// </summary>
public static Expression Equal(this Expression left, Expression right)
{
return Expression.Equal(left, right);
} /// <summary>
/// !=
/// </summary>
public static Expression NotEqual(this Expression left, Expression right)
{
return Expression.NotEqual(left, right);
} #endregion
} /// <summary>
/// Queryable扩展
/// </summary>
public static class QueryableExtensions
{
#region 自定义扩展Queryable /// <summary>
/// Where扩展
/// </summary>
public static IEnumerable<TSource> IWhere<TSource>(this IEnumerable<TSource> source, string linqStr)
{
return source.Where(DynamicLinqFactory.CreateLambda<TSource>(linqStr).Compile());
} /// <summary>
/// FirstOrDefault扩展
/// </summary>
public static TSource IFirstOrDefault<TSource>(this IEnumerable<TSource> source, string linqStr)
{
return source.FirstOrDefault(DynamicLinqFactory.CreateLambda<TSource>(linqStr).Compile());
} /// <summary>
/// Count扩展
/// </summary>
public static Int32 ICount<TSource>(this IEnumerable<TSource> source, string linqStr)
{
return source.Count(DynamicLinqFactory.CreateLambda<TSource>(linqStr).Compile());
} /// <summary>
/// 自定义排序
/// </summary>
public static IOrderedQueryable<TSource> ISort<TSource>(this IQueryable<TSource> source, string orderByProperty, bool asc)
{
string command = asc ? "OrderBy" : "OrderByDescending";
var type = typeof(TSource);
var property = type.GetProperty(orderByProperty);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExpression = Expression.Lambda(propertyAccess, parameter);
var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression));
return (IOrderedQueryable<TSource>)source.Provider.CreateQuery<TSource>(resultExpression);
} /// <summary>
/// 自定义分页
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <param name="nowPage"></param>
/// <param name="pageSize"></param>
/// <returns></returns>
public static IQueryable<TSource> IPaging<TSource>(this IQueryable<TSource> source, int nowPage, int pageSize)
{
return source.ISkip((nowPage - ) * pageSize).ITake(pageSize);
} /// <summary>
/// 自定义Skip
/// </summary>
public static IQueryable<TSource> ISkip<TSource>(this IQueryable<TSource> source, int count)
{
return source.Provider.CreateQuery<TSource>(Expression.Call(
// 类别
typeof(Queryable),
// 调用的方法
"Skip",
// 元素类别
new Type[] { source.ElementType },
// 调用的表达树
source.Expression,
// 参数
Expression.Constant(count)));
} /// <summary>
/// 自定义Take
/// </summary>
public static IQueryable<TSource> ITake<TSource>(this IQueryable<TSource> source, int count)
{
return source.Provider.CreateQuery<TSource>(Expression.Call(
// 类别
typeof(Queryable),
// 调用的方法
"Take",
// 元素类别
new Type[] { source.ElementType },
// 调用的表达树
source.Expression,
// 参数
Expression.Constant(count)));
} /// <summary>
/// 自定义去重复
/// </summary>
public static IEnumerable<TSource> IDistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var seenKeys = new HashSet<TKey>();
return source.Where(element => seenKeys.Add(keySelector(element)));
} /// <summary>
/// 动态赋值
/// </summary>
public static void CopyTo<T>(this object source, T target) where T : class, new()
{
if (source == null)
return; if (target == null)
{
target = new T();
} foreach (var property in target.GetType().GetProperties())
{
// 这里可以判断一下当前属性值是否为空的 source.GetType().GetProperty(property.Name).GetValue(source, null)
target.GetType().InvokeMember(property.Name, BindingFlags.SetProperty, null, target, new object[] { source.GetType().GetProperty(property.Name).GetValue(source, null) });
}
} /// <summary>
/// 移除特殊字段数据
/// </summary>
public static void RemoveSpecialPropertyValue(this object source)
{
var properties = source.GetType().GetProperties();
foreach (var x in properties)
{
if (x.GetAccessors().Any(y => y.IsVirtual))
{
source.GetType().GetProperty(x.Name).SetValue(source, null, null);
}
}
} #endregion
}
}

动态创建生成lambd表达式的更多相关文章

  1. 动态创建Lambda表达式实现高级查询

    需求简介 最近这几天做的东西总算是回归咱的老本行了,给投资管理项目做一个台账的东西,就是类似我们的报表.其 中有一个功能是一个高级查询的需求,在查询条件方面大概有7.8个查询条件.需求就是如果一个条件 ...

  2. C# 动态创建SQL数据库(二) 在.net core web项目中生成二维码 后台Post/Get 请求接口 方式 WebForm 页面ajax 请求后台页面 方法 实现输入框小数多 自动进位展示,编辑时实际值不变 快速掌握Gif动态图实现代码 C#处理和对接HTTP接口请求

    C# 动态创建SQL数据库(二) 使用Entity Framework  创建数据库与表 前面文章有说到使用SQL语句动态创建数据库与数据表,这次直接使用Entriy Framwork 的ORM对象关 ...

  3. Qt5 UI信号、槽自动连接的控件重名大坑(UI生成的槽函数存在一个隐患,即控件重名。对很复杂的控件,不要在 designer 里做提升,而是等到程序启动后,再动态创建,可以避免很多问题)

    对Qt5稍有熟悉的童鞋都知道信号.槽的自动连接机制.该机制使得qt designer 设计的UI中包含的控件,可以不通过显式connect,直接和cpp中的相应槽相关联.该机制的详细文章见 http: ...

  4. 通过动态构建Expression Select表达式并创建动态类型来控制Property可见性

    通过动态构建Expression Select表达式并创建动态类型来控制Property可见性 项目中经常遇到的一个场景,根据当前登录用户权限,仅返回权限内可见的内容.参考了很多开源框架,更多的是在V ...

  5. [C# Expression] 之动态创建表达式

    上一篇中说到了 Expression 的一些概念性东西,其实也是为了这一篇做知识准备.为了实现 EFCore 的多条件.连表查询,简化查询代码编写,也就有了这篇文章.   在一些管理后台中,对数据进行 ...

  6. C#动态执行字符串(动态创建代码)

    在编写C#程序的时候,有时我们需要动态生成一些代码并执行.然而C#不像JavaScript有一个Eval函数,可以动态的执行代码.所有这些功能都要我们自己去完成.如下是实例. 动态创建代码: usin ...

  7. Springboot定时任务原理及如何动态创建定时任务

    一.前言 上周工作遇到了一个需求,同步多个省份销号数据,解绑微信粉丝.分省定时将销号数据放到SFTP服务器上,我需要开发定时任务去解析文件.因为是多省份,服务器.文件名规则.数据规则都不一定,所以要做 ...

  8. WinForm用户控件、动态创建添加控件、timer控件--2016年12月12日

    好文要顶 关注我 收藏该文 徐淳 关注 - 1 粉丝 - 3       0 0     用户控件: 通过布局将多个控件整合为一个控件,根据自己的需要进行修改,可对用户控件内的所有控件及控件属性进行修 ...

  9. 《Entity Framework 6 Recipes》中文翻译系列 (38) ------ 第七章 使用对象服务之动态创建连接字符串和从数据库读取模型

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第七章 使用对象服务 本章篇幅适中,对真实应用中的常见问题提供了切实可行的解决方案. ...

随机推荐

  1. ORACLE-osi分层模型.md

    一. 标准化组织ISOISO:国际标准化组织   ( International Organization for Standardization )OSI:开放系统互联   ( open syste ...

  2. 前端框架之Vue(6)-列表渲染

    用v-for把一个数组对应为一组元素 我们用 v-for 指令根据一组数组的选项列表进行渲染. v-for 指令需要使用 item in items 形式的特殊语法, items 是源数据数组并且 i ...

  3. javaScript刷新页面

    刷新页面有一下几种: 1.直接在页面上: 每两秒刷新页面 <meta http-equiv="refresh" content="2"> 2.每秒刷 ...

  4. Go包管理工具Vendor使用

    一.Go包管理工具Vendor 一.使用步骤 1.首先,从go get -u github.com/kardianos/govendor下载govendor工具到本地. 2.govendor使用时,必 ...

  5. (转)Thread中yield方法

    先上一段代码 public class YieldExcemple { public static void main(String[] args) { Thread threada = new Th ...

  6. 【Java】-NO.12.Java.2.OCJP.1.001-【Java OCJP】-

    1.0.0 Summary Tittle:[Java]-NO.12.Java.2.OCJP.1.001-[Java OCJP]- Style:Java Series:OCJP Since:2017-0 ...

  7. Shiro权限管理框架详解

    1 权限管理1.1 什么是权限管理 基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被 ...

  8. win10系统180天试用到期需要激活

    激活时激活不了,需要先修复下:4-Win10yjjh_XiTongZhiJia 链接: https://pan.baidu.com/s/1M_aNu2bqtEVn3l8FXsa91A 提取码: 784 ...

  9. php开启pdo扩展

    在Windows环境下php 5.1以上版本中,pdo和主要数据库的驱动同php一起作为扩展发布,要激活它们只需要简单地编辑php.ini文件. 打开php.ini配置文件,找到extension=p ...

  10. 关于 CGI,Fastcgi和php-fpm 理解

    首先,CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的,方便CGI程序的编写者. web server(比如说nginx)只是内容的分发者.比如,如果请求/index.h ...