排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术
分类:
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; }
但是这样是不行的,每次都会覆盖到前面的
下面这种写法可以实现动态的and,但是不好实现动态or,这种复杂的条件
var query = context.Article; var queryable = query.Where(a => a.UserId == userid && a.IsDelete != 1 && a.IsPrivate != 1); //动态构建条件 foreach (string keyword in _keywords) { queryable = queryable.Where(a => a.Title.Contains(keyword)); }
使用动态组装条件的方法:
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);
当然如果不是动态的部分就非常简单了,直接一起写完就好了,比如下面这些条件都是必须要有的
var predicate = PredicateBuilder.False<Article>(); predicate.And(a => a.UserId == uid && a.Title == _article.Title && (a.IsDelete == null || a.IsDelete != 1));
需要根据某些情况动态添加的条件在进行判断添加即可
//ef的动态条件 if (_article.IsPrivate == 1) { predicate.And(a => a.IsPrivate == 1); }
贴一个多条件的多(2019-9-17 时间会改变太多东西)
参考文章:
http://www.albahari.com/nutshell/predicatebuilder.aspx
欢迎加群讨论技术,群:677373950(满了,可以加,但通过不了),2群:656732739
评价