(转)Entity Framework4.1实现动态多条件查询、分页和排序

原文:http://www.cnblogs.com/ahui/archive/2011/08/04/2127282.html

EF通用的分页实现:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

/// <summary>

/// 根据条件分页获得记录

/// </summary>

/// <param name="where">条件</param>

/// <param name="orderBy">排序</param>

/// <param name="ascending">是否升序</param>

/// <param name="pageIndex">当前页码</param>

/// <param name="pageSize">每页大小</param>

/// <param name="totalRecord">总记录数</param>

/// <returns>记录列表</returns>

public virtual List<T> GetMany(Expression<Func<T, bool>> where, string orderBy, bool ascending, int pageIndex, int pageSize, out int totalRecord)

{

    totalRecord = 0;

    where = where.And(u => u.Flag != (int)Flags.Delete);

    var list = dbset.Where(where);

    totalRecord = list.Count();

    if (totalRecord <= 0) return new List<T>();

    list = list.OrderBy(orderBy, ascending).Skip((pageIndex - 1) * pageSize).Take(pageSize);

    return list.ToList();

}

动态排序扩展:

public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName, bool ascending) where T : class

{

    Type type = typeof(T);

    PropertyInfo property = type.GetProperty(propertyName);

    if (property == null)

        throw new ArgumentException("propertyName", "Not Exist");

    ParameterExpression param = Expression.Parameter(type, "p");

    Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property);

    LambdaExpression orderByExpression = Expression.Lambda(propertyAccessExpression, param);

    string methodName = ascending ? "OrderBy" : "OrderByDescending";

    MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName, new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression));

    return source.Provider.CreateQuery<T>(resultExp);

}

如果要通过Expression获取字段,可以使用以下代码:

/// <summary>

/// 获取对应的字段名

/// </summary>

/// <typeparam name="TSource"></typeparam>

/// <param name="keySelector"></param>

/// <returns></returns>

public static string GetMemberName<TSource, TKey>(Expression<Func<TSource, TKey>> keySelector)

{

    string fieldName = null;

    var exp = keySelector.Body as UnaryExpression;

    if (exp == null)

    {

        var body = keySelector.Body as MemberExpression;

        fieldName = body.Member.Name;

    }

    else

    {

        fieldName = (exp.Operand as MemberExpression).Member.Name;

    }

    return fieldName;

}

多条件组合(参见老赵相关文章):

/// <summary>

/// 统一ParameterExpression

/// </summary>

internal class ParameterReplacer : ExpressionVisitor

{

    public ParameterReplacer(ParameterExpression paramExpr)

    {

        this.ParameterExpression = paramExpr;

    }

    public ParameterExpression ParameterExpression { get; private set; }

    public Expression Replace(Expression expr)

    {

        return this.Visit(expr);

    }

    protected override Expression VisitParameter(ParameterExpression p)

    {

        return this.ParameterExpression;

    }

}

public static class PredicateExtensionses

{

    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>> exp_left, Expression<Func<T, bool>> exp_right)

    {

        var candidateExpr = Expression.Parameter(typeof(T), "candidate");

        var parameterReplacer = new ParameterReplacer(candidateExpr);

        var left = parameterReplacer.Replace(exp_left.Body);

        var right = parameterReplacer.Replace(exp_right.Body);

        var body = Expression.And(left, right);

        return Expression.Lambda<Func<T, bool>>(body, candidateExpr);

    }

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> exp_left, Expression<Func<T, bool>> exp_right)

    {

        var candidateExpr = Expression.Parameter(typeof(T), "candidate");

        var parameterReplacer = new ParameterReplacer(candidateExpr);

        var left = parameterReplacer.Replace(exp_left.Body);

        var right = parameterReplacer.Replace(exp_right.Body);

        var body = Expression.Or(left, right);

        return Expression.Lambda<Func<T, bool>>(body, candidateExpr);

    }

}

  

调用示例:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

public static PagedList<UsersDTO> GetUsers(int pageIndex, int pageSize, string orderBy, bool ascending,

    Companys company, string email, string nickName, bool? isAdmin, UserStatus userStatus)

{

    PagedList<UsersDTO> result = new PagedList<UsersDTO>(pageIndex, pageSize);

    int totalRecord = 0;

    Expression<Func<Users, bool>> where = PredicateExtensionses.True<Users>();

    if (company != Companys.All) where = where.And(u => u.Company == (int)company);

    if (!string.IsNullOrEmpty(email)) where = where.And(u => u.Email.Contains(email));

    if (!string.IsNullOrEmpty(nickName)) where = where.And(u => u.NickName.Contains(nickName));

    if (isAdmin.HasValue)

    {

        if (isAdmin.Value) where = where.And(u => u.IsAdmin == 1);

        else where = where.And(u => u.IsAdmin == 0);

    }

    if (userStatus != UserStatus.All) where = where.And(u => u.UserStatus == (int)userStatus);

    if (string.IsNullOrEmpty(orderBy))

        orderBy = MapHelper.GetMappedName<UsersDTO, Users>(u => u.UserId);

    else

        orderBy = MapHelper.GetMappedName<UsersDTO, Users>(orderBy);

    List<Users> list = _usersDao.GetMany(where, orderBy, ascending, pageIndex, pageSize, out totalRecord);

    result.TotalRecordCount = totalRecord;

    foreach (var data in list)

    {

        result.Items.Add(Mapper.Map<Users, UsersDTO>(data));

    }

    return result;

}

  

上述方法的缺点是无法针对2个字段一起排序,不过只要修改排序参数还是可以实现的!

另外这种分页查询只能针对一个表或者视图

时间: 2024-10-29 04:10:04

(转)Entity Framework4.1实现动态多条件查询、分页和排序的相关文章

动态多条件查询分页以及排序(一)--MVC与Entity Framework版url分页版

一.前言 多条件查询分页以及排序  每个系统里都会有这个的代码 做好这块 可以大大提高开发效率  所以博主分享下自己的6个版本的 多条件查询分页以及排序 二.目前状况 不论是ado.net 还是EF 在做多条件搜索时 都有这类似的代码 这样有几个不好的地方 1.当增加查询条件,需要改代码,对应去写相应的代码. 2.对多表查询以及or的支持 不是很好.而我们很常见的需求不可能是一个表的查询 3. 这样写表示层直接出现 了SQL语句 或者 linq 的拉姆达表达式  这是很不好的 表示层不应该知道数

EntityFramework动态多条件查询与Lambda表达式树

          在常规的信息系统中, 我们有需要动态多条件查询的情况, 例如UI上有多个选择项可供用户选择多条件查询数据. 那么在.net平台Entity Framework下, 我们用Lambda表达式树如何实现, 这里我们需要一个PredicateBuilder的UML类图: 实现的代码是这样的: /// <summary> /// Enables the efficient, dynamic composition of query predicates. /// </summ

Silverlight学习(四) domainservice动态多条件查询

上次讲了silverlight+MVVN+EF的简单框架,能够实现简单的数据CURD,但是多条件动态的查询一直没有实现.在网上查阅了很多资料,发现自己走了很多误区,代码很难调试正确. 这次的查询是基于上次的查询,只是增加了一个查询条件,动态多条件的查询的重点是获取查询的语言. 1 private string GetSql() 2 { 3 string query = "1=1"; 4 if (!string.IsNullOrEmpty(searchText.name)) 5 { 6

Mysql动态多条件查询

动态多条件查询是一类经常遇到的问题. 在Mysql里面可以用语句简单的解决. SELECT * FROM product WHERE price = IF('{0}' = '', price, '{0}') AND name LIKE IF('{1}' = '', name, '%{1}%') 这里的price和name分别为产品表中的两个字段名,{}标志位是我们要将参数替换进去的地方,这样在查询页面只需调用SQL模板语句,并替换相应的参数即可.(假设用户没有过滤价格,则{0}为空,那么得到的S

Django-rest-framework多条件查询/分页/多表Json

Django-rest-framework多条件查询/分页/多表Json django-rest-framework多条件查询需要覆写ListAPIView.get_queryset方法,代码示例: def get_queryset(self):     """     使用request.query_params实现多条件查询,也可以使用django filter ,较简单的     方法是在filter_fields中指定要过滤的字段,但只能表示等值,不灵活,灵活的方式是

基于Struts2、Spring、Hibernate实现的包含多条件查询分页的基础Dao层帮助jar包实现

操作数据库常用操作就是增删查改,每做一次就写一次这些操作太麻烦,也没必要,特别是写多条件查询并分页时,太痛苦了,所以抽空写了个dao帮助jar,导入即搞定!妈妈再有不用担心我的项目了! 转载请注明出处!!! 使用说明: 1.类的使用请参照文档说明,不懂可以结合例子demo! 2.分页jsp书写,只需将分页条件包在<form action="地址" id="pageForm">中即可,然后把jar中的pageJsp中的pageView.jsp拷出来,在数据

基于Struts2、Spring、Hibernate实现的包括多条件查询分页的基础Dao层帮助jar包实现

操作数据库经常使用操作就是增删查改.每做一次就写一次这些操作太麻烦,也不是必需,特别是写多条件查询并分页时.太痛苦了,所以抽出时间写了个dao帮助jar.导入即搞定!妈妈再有不用操心我的项目了! 转载请注明出处! ! ! 使用说明: 1.类的使用请參照文档说明,不懂能够结合样例demo. 2.分页jsp书写,仅仅需将分页条件包在<form action="地址" id="pageForm">中就可以.然后把jar中的pageJsp中的pageView.j

mybatis动态sql片段与分页,排序,传参的使用

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 注意:使用mappe

多条件查询分页

分页实现后,通过多条件查询后,内容如果需要分页,容易出现切换页面内容跳转到查询前的内容.解决方法可以通过将查询后的内容建表,然后在进行分页. <?php require_once "../wenjian/DBDA.class.php"; require_once "../wenjian/page.class.php"; // $obj = "select * from book WHERE is_delete= '0' "; $obj =