.Net Linq动态表达式

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

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

    /// <summary>
    /// 动态linq组合
    /// </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.Or(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.And(expr1.Body, invokedExpr), expr1.Parameters);
        }
    }

调用方法

Expression<Func<Account, bool>> ExpWhere = PredicateBuilder.True<Account>();
          
            //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;
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容