应无所住,而生其心
排名
1
文章
858
粉丝
112
评论
163
net core webapi post传递参数
庸人 : 确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

ef6动态添加条件

11920人阅读 2019/2/10 17:12 总访问:5168079 评论:0 收藏:0 手机
分类: EF


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

  1.   public List<Article> GetArtByKeys(List<string> _keywords)
  2.    {
  3.             CNBlog_ServerContext ef = EFHelper.GetInstance();
  4.             var query = ef.Art;
  5.             //循环添加条件
  6.             foreach (string keyword in _keywords)
  7.             {
  8.                 query.Where(a => a.Title.Contains(keyword));
  9.             }
  10.             List<Art> articles = query.ToList();
  11.             return arts;
  12.    }

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


下面这种写法可以实现动态的and,但是不好实现动态or,这种复杂的条件

  1. var query = context.Article;
  2. var queryable = query.Where(a => a.UserId == userid && a.IsDelete != 1 && a.IsPrivate != 1);
  3. //动态构建条件
  4. foreach (string keyword in _keywords)
  5. {
  6.     queryable = queryable.Where(a => a.Title.Contains(keyword));
  7. }



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

  1.   public List<Article> GetArticleByKeys(List<string> _keywords)
  2.    {
  3.             CNBlog_ServerContext ef = EFHelper.GetInstance();
  4.             //先构建一个查询条件
  5.             var predicate = PredicateBuilder.False<Art>();
  6.             foreach (string keyword in _keywords)
  7.             {
  8.                 //循环去添加条件
  9.                 predicate = predicate.Or(a => a.Title.Contains(keyword));
  10.             }
  11.             List<Article> articles = ef.Art.Where(predicate).ToList();
  12.             return articles;
  13.    }


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

  1.    public static class PredicateBuilder
  2.     {
  3.         public static Expression<Func<T, bool>> True<T>() { return f => true; }
  4.         public static Expression<Func<T, bool>> False<T>() { return f => false; }
  5.         public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
  6.                                                             Expression<Func<T, bool>> expr2)
  7.         {
  8.             var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
  9.             return Expression.Lambda<Func<T, bool>>
  10.                   (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
  11.         }
  12.         public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
  13.                                                              Expression<Func<T, bool>> expr2)
  14.         {
  15.             var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
  16.             return Expression.Lambda<Func<T, bool>>
  17.                   (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
  18.         }
  19.     }



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

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

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

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


思路:

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

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

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

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

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

  1. outer = outer.And (inner);


当然如果不是动态的部分就非常简单了,直接一起写完就好了,比如下面这些条件都是必须要有的

  1. var predicate = PredicateBuilder.False<Article>();
  2. predicate.And(a => a.UserId == uid && a.Title == _article.Title && (a.IsDelete == null || a.IsDelete != 1));

需要根据某些情况动态添加的条件在进行判断添加即可

  1. //ef的动态条件
  2.  if (_article.IsPrivate == 1)
  3.  {
  4.        predicate.And(a => a.IsPrivate == 1);
  5.  }

贴一个多条件的多(2019-9-17 时间会改变太多东西)



参考文章:

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

欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价