/// <summary>/// 表达式扩展/// </summary>public static class ExpressionExtension{/// <summary>/// 使用AndAlso合并表达式/// </summary>/// <param name="exprs"></param>/// <returns></returns>public static Expression<T> AndAlso<T>(this IList<Expression<T>> exprs){if (exprs.Count == 0) return null;if (exprs.Count == 1) return exprs[0];var leftExpr = exprs[0];var left = leftExpr.Body;for (int i = 1; i < exprs.Count; i++){var expr = exprs[i];var visitor = GetReplaceExpressionVisitor(expr.Parameters, leftExpr.Parameters);var right = visitor.Visit(expr.Body);left = Expression.AndAlso(left, right);}return Expression.Lambda<T>(left, leftExpr.Parameters);}/// <summary>/// 使用AndAlso合并表达式/// </summary>/// <typeparam name="T"></typeparam>/// <param name="left"></param>/// <param name="right"></param>/// <returns>left AndAlso right</returns>public static Expression<T> AndAlso<T>(this Expression<T> left, Expression<T> right){return AndAlso(new List<Expression<T>>() { left, right });}/// <summary>/// 使用OrElse合并表达式/// </summary>/// <typeparam name="T"></typeparam>/// <param name="exprs"></param>/// <returns></returns>public static Expression<T> OrElse<T>(this IList<Expression<T>> exprs){if (exprs.Count == 0) return null;if (exprs.Count == 1) return exprs[0];var leftExpr = exprs[0];var left = leftExpr.Body;for (int i = 1; i < exprs.Count; i++){var expr = exprs[i];var visitor = GetReplaceExpressionVisitor(expr.Parameters, leftExpr.Parameters);var right = visitor.Visit(expr.Body);left = Expression.OrElse(left, right);}return Expression.Lambda<T>(left, leftExpr.Parameters);}/// <summary>/// 使用OrElse合并表达式/// </summary>/// <typeparam name="T"></typeparam>/// <param name="left"></param>/// <param name="right"></param>/// <returns>left OrElse right</returns>public static Expression<T> OrElse<T>(this Expression<T> left, Expression<T> right){return OrElse(new List<Expression<T>>() { left, right });}/// <summary>/// 构建visitor/// </summary>/// <param name="oldParameters"></param>/// <param name="newParameters"></param>/// <returns></returns>private static ReplaceExpressionVisitor GetReplaceExpressionVisitor(ReadOnlyCollection<ParameterExpression> oldParameters, ReadOnlyCollection<ParameterExpression> newParameters){Dictionary<Expression, Expression> dic = new Dictionary<Expression, Expression>();for (int i = 0; i < oldParameters.Count; i++){dic.Add(oldParameters[i],newParameters[i]);}return new ReplaceExpressionVisitor(dic);}}使用
string connectString = "Data Source=.;Initial Catalog=RportTest;Integrated Security=True";var optionsBuilder = new DbContextOptionsBuilder<TestContext>();optionsBuilder.UseSqlServer(connectString);using (TestContext ctx = new TestContext(optionsBuilder.Options)){Expression<Func<ReportData, bool>> epxr1 = report => report.ID == 2023;Expression<Func<ReportData, bool>> epxr2 = report => report.Name == "test1";var epxr3 = new List<Expression<Func<ReportData, bool>>>() { epxr1, epxr2 };var andPredicate = epxr3.AndAlso();var andQuery = ctx.ReportData.Where(andPredicate);string andSql = andQuery.ToQueryString();var andResult = andQuery.ToList();var orPredicate = epxr3.OrElse();var orQuery = ctx.ReportData.Where(orPredicate);string orSql = orQuery.ToQueryString();var orResult = orQuery.ToList();}
经验总结扩展阅读
- .NET Core C#系列之XiaoFeng.Threading.JobScheduler作业调度
- SpringBoot框架SpEL表达式注入漏洞复现与原理分析
- 【番外篇】Rust环境搭建+基础开发入门+Rust与.NET6、C++的基础运算性能比较
- .NET周报【10月第2期 2022-10-17】
- 聊一聊被 .NET程序员 遗忘的 COM 组件
- 细聊.Net Core中IServiceScope的工作方式
- asp.net core web 解决方案多项目模板制作打包总结
- ubuntu-22.04 树莓派Zero 2 W通过.NET6和libusb操作USB读写
- 上 学习ASP.NET Core Blazor编程系列六——新增图书
- Azure DevOps Pipelines部署.Net Core 应用到Kubernetes
