我个人学习新技术有一个方法,如果遇到问题会根据以前的经验来寻找一些类似的解决方法。有人会说,如果这个问题在你的学习或者工作生涯中都没有遇到过呢?很简单,通过搜索资料或查阅相关书籍学习别人的经验。
在如今的每个商业应用开发过程中,基本上开发人员都会遇到一个问题,就是如何根据不同的条件构建查询表达式或Sql查询语句。根据之前的使用Hibernate或者JPA的开发经验,自然想到,根据不同的条件判断拼接Hql语句或者叫Jpql语句。但是,在使用EF6开发中遇到这种问题想手动的拼接Lambda查询表达式,有点困难。幸好,通过搜索资料找到了国外高人的解决方案,通过PredicateBuilder实现EF6多条件动态查询。
PredicateBuilder源码
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
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);
}
}
PredicateBuilder其实是LINQKit的一部分,LINQKit是适用于LINQ to SQL和Entity Framework功能增强版拓展工具。
注:如果你在使用LINQ to SQL,你只要把PredicateBuilder加入你的项目即可。但是,如果你在使用Entity Framework框架,你将需要LINQKit提供的AsExpandable功能。所以必须得在你的项目中要么加入LINQKit.dll的引用要么直接拷贝LINQKit的源代码进去。
如何使用PredicateBuilder
以实际项目中用户的多条件查询为例,详细步骤如下:
1、把LINQKit.dll引用或者其源代码加入项目中;
2、在DAL层使用AsExpandable方法查询;
public IQueryable<T> LoadLinqKitEntities(Expression<Func<T, bool>> whereLambda) { return db.Set<T>().AsExpandable().Where(whereLambda).AsQueryable(); }
3、在BLL层根据传递的参数拼接动态的Lambda表达式。
internal IList<UserInfo> GetUsersByParam(UserInfo userInfo) { Expression<Func<UserInfo, bool>> eps = PredicateBuilder.True<UserInfo>(); if (userInfo.DepartmentId != null&&userInfo.DepartmentId>0) { eps = eps.And(u => u.DepartmentId == userInfo.DepartmentId); } if (userInfo.Name.Length > 0) { eps = eps.And(u => u.RealName.Contains(userInfo.Name)); } eps = eps.And(u => u.Name != "admin"); return efDal.LoadLinqKitEntities(eps).Select(u => u).ToList(); }
通过以上几步就可以实现在EF6中动态的拼接Lambda表达式,支持动态查询了,动手试试吧。
原创文章,转载请注明: 转载自追风筝的coder
本文链接地址: 使用PredicateBuilder实现EF6多条件动态查询
http://vtocode.com/blog/index.php/2014/12/03/ef6-multi-condition-dynamic-query/