前言
Entity Framework 6(EF 6)中的 Where 方法用于筛选数据库中的数据并返回符合条件的结果,但 Where 方法只能进行简单的筛选条件,例如相等、大于、小于等简单条件,如果需要处理更复杂的逻辑条件,则需要使用其他方法或手动处理,增加了代码复杂性。
本文分享一个扩展 .NET EF 6 Where 的方法。
代码 & 步骤
-
写 Where 的表达扩展类,留意注释
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Linq.Expressions; namespace ERP.DAL.Repository.Extensions { /// <summary> /// Linq 表达式扩展类 /// </summary> public static class ExpressionExtensions { /// <summary> /// 添加And条件 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second) { return first.AndAlso<T>(second, Expression.AndAlso); } /// <summary> /// 添加Or条件 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second) { return first.AndAlso<T>(second, Expression.OrElse); } /// <summary> /// 合并表达式以及参数 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="expr1"></param> /// <param name="expr2"></param> /// <param name="func"></param> /// <returns></returns> private static Expression<Func<T, bool>> AndAlso<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2, Func<Expression, Expression, BinaryExpression> func) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); return Expression.Lambda<Func<T, bool>>(func(left, right), parameter); } /// <summary> /// 继承表达式树的访问者或重写者。 /// </summary> private class ReplaceExpressionVisitor : ExpressionVisitor { private readonly Expression _oldValue; private readonly Expression _newValue; public ReplaceExpressionVisitor(Expression oldValue, Expression newValue) { _oldValue = oldValue; _newValue = newValue; } public override Expression Visit(Expression node) { if (node == _oldValue) return _newValue; return base.Visit(node); } } } }
-
使用
Expression<Func<hospital, bool>> filter = u => u.status != -1; filter = filter.And(c => c.name.Contains("第三医院")); filter = filter.Or(c => c.name.Contains("第二医院")); List<hospital> list = new List<hospital>(); list = list.AsQueryable().Where(filter).ToList();
总结
通过这个 Where 扩展类,可以很方便地处理更复杂的逻辑条件,比如 OR
逻辑。直接将代码复制到项目即可使用。
往期精彩
- 分享一个 .NET 通过监听器拦截 EF 消息写日志的详细例子
- 不会使用 EF Core 的 Code First 模式?来看看这篇文章,手把手地教你
- EF Core 性能很差?试试这 6 个小技巧
- 如何在 EF Core 中使用乐观并发控制
- EF Core 在实际开发中,如何分层?
我是老杨,一个奋斗在一线的资深研发老鸟,让我们一起聊聊技术,聊聊程序人生,共同学习,共同进步