前景:
今天我做项目的时候,要使用多条件查询,但是又不想用SQL语句拼接查询,然后在网上找到了LinqKit可以实现这种操作并学习,现在来教大家怎么实现
这种查询:
LinqKit作用:
在使用Linq查询的时候,特别是如果你在使用Entiry Framwork,有时会遇到动态查询的情况(客户的查询条件是不固定的拼接查询)。
我们能想到的第一方案应该是拼接SQL,的确这样是可以达到我们的目的的。但这样又会破坏程序的一至性,本来使用Entiry Framwork的目标就是用面向对象的方式操纵数据库,这样我们又要开始写SQL语句了。
1.首先在你的项目中引入PredicateBuilder依赖:【引用】——【管理NuGet程序包】——找到【LinqKit】
1.1如果有个"v"说明安装成功。安装成功后需要在自己项目中引入【linqKit】
1.2也可以自己新建一个class功能类,用来做多条件查询。
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>> 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); } 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, Func<Expression<Func<T, bool>>> func) { Expression<Func<T, bool>> expr2 = func(); var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>()); return Expression.Lambda<Func<T, bool>> (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters); } public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Func<Expression<Func<T, bool>>> func) { Expression<Func<T, bool>> expr2 = func(); var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>()); return Expression.Lambda<Func<T, bool>> (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters); } }
2.然后在自己项目中进行查询(我使用的是第二种,自己新建了一个class)。
//创建PredicateBulider对象 var where = PredicateBuilder.True<UserInfo>(); if (!string.IsNullOrEmpty(zhanghao)) { where = where.And(u => u.UserInfoId == zhanghao); } if (!string.IsNullOrEmpty(youxiang)) { where = where.And(u => u.UserInfoEmail == youxiang); } if (!string.IsNullOrEmpty(xingming)) { where = where.And(u => u.UserInfoNameId == xingming); } if (!string.IsNullOrEmpty(dianhua)) { where = where.And(u => u.UserInfoPhone == dianhua); } if (!string.IsNullOrEmpty(xingbie)) { where = where.And(u => u.UserInfoGender == xingbie); } //进行查询 var res = db.Set<UserInfo>().Where(where.Compile());
补充:
1.创建PredicateBuilder对象
var where = PredicateBuilder.True<UserInfo>();可以理解为创建一个初始化为True的Predicate。
注意:如果你是要创建一个OR组成的Predicate就不能把它初始化为True因为这样这个表达试永远为True了。
var where = PredicateBuilder.False<TrendStatics>();可以理解为创建一个初始化为False的Predicate。
注意:如果你是要创建一个AND组成的Predicate就不能把它初始化为False因为这样这个表达试永远为False了。
2.PredicateBuilder对象拼接
//全And
var list = Enumerable.Range(1, 100);
var where = PredicateBuilder.True<int>(); where = where.And(x => x >= 50); where = where.And(x => x <= 70); var res = list.Where(where.Compile());
//全or
var list = Enumerable.Range(1, 100); var where = PredicateBuilder.False<int>(); where = where.Or(x => x == 50); where = where.Or(x => x == 70); var res = list.Where(where.Compile());
//各种组合
var list = Enumerable.Range(1, 100); var where = PredicateBuilder.True<int>(); where = where.And(x => x >= 50); where = where.And(x => x <= 70); var subwhere = PredicateBuilder.False<int>(); subwhere = subwhere.Or(x => x == 60); subwhere = subwhere.Or(x => x == 61); where = where.And(subwhere); var res = list.Where(where.Compile());
3.PredicateBuilder对象的使用
- 针对集合Linq查询(2种方法):
var res = list.Where(where.Compile());var res = list.AsQueryable().Where(where);
- 针对Entity Framework
var res = table.Where(where.Expand());