代码改变世界

ef动态拼接

2022-07-29 16:09  NO.27  阅读(203)  评论(0编辑  收藏  举报

1、首先定义类

    /// <summary>
    /// EF拼接
    /// </summary>
    public static class PredicateBuilder
    {
        public static Expression<Func<T, bool>> True<T>() { return f => true; }
        public static Expression<Func<T, bool>> False<T>() { return f => false; }

        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                            Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
        }

        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                             Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
        }
    }

2、使用

 //定义
 var where = PredicateBuilder.True<TaskIndex>();
 var whereOr = PredicateBuilder.False<TaskIndex>();
 bool hasOr = false;
 //固定值
 where = where.And(p => p.TaskSendTime >= beginTime && p.TaskSendTime <= endTime && p.Status == 4);
 //密级
 if (SecretLevel != null && SecretLevel.Length > 0)
 {
     var levels = SecretLevel.Split(',');
     foreach (var value in levels)
     {
         if (value.Trim() == "isEmpty") //默认值的NULL
         {
             whereOr = whereOr.Or(p => p.SecretLevel == null);
         }
         else
         {
             whereOr = whereOr.Or(p => p.SecretLevel == value);
         }
         hasOr = true;
     }
 }
 else
 {
     if (!IsSecret)
     {
         whereOr = whereOr.Or(p => p.SecretLevel == null ||  p.SecretLevel != "石油商密");
         hasOr = true;
     }
 }
 //任务名
 if (!string.IsNullOrEmpty(TaskName)) {
     where = where.And(p => p.TaskName.Contains(TaskName));
 }
 //机构查询
 if (type == 1 || type == 2)
 {
     if (subOrgIds.Count > 0) {
         where = where.And(p => subOrgIds.Contains(Guid.Parse(p.ReceiveIncID)));
     }
 }
 else
 {
     if (subOrgIds.Count > 0)
     {
         where = where.And(p => subOrgIds.Contains(Guid.Parse(p.ReceiveOrgID)));
     }
 }
 //拼接OR
 if (hasOr) {
     where = where.And(whereOr);
 }
 var tasks = context.TaskIndexs.AsNoTracking().Where(where.Compile()).OrderByDescending(i=>i.TaskSendTime).ToList();

注意:

上述代码False和True含义完全不一样,如果为True为如下效果

select * from table where name='一班' or id=1 or id=2 or id=3

如果为False为如下

select * from table where name='一班' and (id=1 or id=2 or id=3)

3、其他方式

        Expression<Func<测试实体类, bool>> condition = c => (c.字段c == 某数据实体.字段c && c.字段d == 某数据实体.字段d &&
           ((c.字段a > 某数据实体.字段a && c.字段b != 某数据实体.字段b) || (c.字段a == 某数据实体.字段a && c.字段b > 某数据实体.字段b)));