tnblog
首页

ef6动态添加条件

186人阅读 2019/2/10 17:12 评论:0 手机浏览 收藏
分类: EF


例如我们要匹配一个集合中的所有关键字,我们首先想到的做法是这样的

  public List<Article> GetArtByKeys(List<string> _keywords)
   {
            CNBlog_ServerContext ef = EFHelper.GetInstance();

            var query = ef.Art;
            //循环添加条件
            foreach (string keyword in _keywords)
            {
                query.Where(a => a.Title.Contains(keyword));
            }

            List<Art> articles = query.ToList();

            return arts;
   }

但是这样是不行的,每次都会覆盖到前面的



使用动态组装条件的方法:

  public List<Article> GetArticleByKeys(List<string> _keywords)
   {
            CNBlog_ServerContext ef = EFHelper.GetInstance();

            //先构建一个查询条件
            var predicate = PredicateBuilder.False<Art>();
            foreach (string keyword in _keywords)
            {
                //循环去添加条件
                predicate = predicate.Or(a => a.Title.Contains(keyword));
            }
            List<Article> articles = ef.Art.Where(predicate).ToList();

            return articles;
   }


其中需要的工具类PredicateBuilder代码如下,注意相关的名称空间要引入,因为里边用到了扩展方法

   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);
        }
    }



and,or复杂多条件组合方法

例如我们要组合一个这样的复杂一点的条件

p => p.Price > 100 &&
     p.Price < 1000 &&     (p.Description.Contains ("foo") || p.Description.Contains ("far"))

难点在于or外面是有括号的,要和其他两个条件进行and连接,其实知道思路后就不那么难了


思路:

1:先单独构建好or的条件

var inner = PredicateBuilder.False<Product>();
inner = inner.Or (p => p.Description.Contains ("foo"));
inner = inner.Or (p => p.Description.Contains ("far"));

2:在单独构建好and的条件

var outer = PredicateBuilder.True<Product>();
outer = outer.And (p => p.Price > 100);
outer = outer.And (p => p.Price < 1000);

3:把这两个条件进去and连接一下就搞定了!

outer = outer.And (inner);



参考文章:

http://www.albahari.com/nutshell/predicatebuilder.aspx

评价
自己阳光积极向上,就会吸引阳光积极向上的人和事
文章
6
评论
8
分类
16
关注
16
{{item.ArticleTitle}}
{{item.BlogName}} : {{item.Content}}