.Net Linq动态表达式

linq中的表达式是对Func和Action形式的委托做了一层封装,在内存中以表达式数形式存储,这种存储方式数据结构明了,有利于进行Linq to XXX查询(如很容易将linq转成sql)。还有一点linq查询默认都是延迟加载的,只有使用结果时才执行真正的查询操作(如 在执行first,last,single,count,ToList,toXXX时才进行真正的查询),这种设计将查询的方式和查询的执行进行了解耦,使得我们可以将查询方法分成多个步骤来创建,linq表达式的保存这些查询方法(就是封装的委托),在我们需要使用查询结果时,通过一个完整的方法(linq表达式组合在一起)去查询,减少了对集合的查询次数,这种特性对数据库查询很有利。

在某些场合,需要动态的编译表达式,代码如下

    /// 
    /// 动态linq组合
    /// 
    public static class PredicateBuilder
    {
        public static Expression> True()
        { return f => true; }
        public static Expression> False() { return f => false; }

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

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

调用方法

Expression> ExpWhere = PredicateBuilder.True();
          
            //if (id != -1)
            //    ExpWhere = ExpWhere.And(q => q.ID.Equals(id));

            if (Levelid != -1)
                ExpWhere = ExpWhere.And(q => q.UserLevelID.Equals(Levelid));

            var Accounts = db.Accounts.Where(t => t.Status.Equals(0)).Where(ExpWhere.Compile()).OrderBy(t => t.ID).Select(t => new SelectListItem
            {
                Text = t.TrueName,
                Value = t.ID.ToString(),
            }).AsQueryable();
            return Accounts;

你可能感兴趣的:(.Net Linq动态表达式)