原文: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个字段一起排序,不过只要修改排序参数还是可以实现的!

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

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

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

    一.前言 多条件查询分页以及排序  每个系统里都会有这个的代码 做好这块 可以大大提高开发效率  所以博主分享下自己的6个版本的 多条件查询分页以及排序 二.目前状况 不论是ado.net 还是EF ...

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

              在常规的信息系统中, 我们有需要动态多条件查询的情况, 例如UI上有多个选择项可供用户选择多条件查询数据. 那么在.net平台Entity Framework下, 我们用Lambd ...

  3. Mysql动态多条件查询

    动态多条件查询是一类经常遇到的问题. 在Mysql里面可以用语句简单的解决. SELECT * FROM product WHERE price = IF('{0}' = '', price, '{0 ...

  4. sql语句之条件,分页,排序

    sql语句之条件,分页,排序

  5. mybatis的mapper特殊字符转移以及动态SQL条件查询

    前言 我们知道在项目开发中之前使用数据库查询,都是基于jdbc,进行连接查询,然后是高级一点jdbcTemplate进行查询,但是我们发现还是不是很方便,有大量重复sql语句,与代码偶合,效率低下,于 ...

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

    上次讲了silverlight+MVVN+EF的简单框架,能够实现简单的数据CURD,但是多条件动态的查询一直没有实现.在网上查阅了很多资料,发现自己走了很多误区,代码很难调试正确. 这次的查询是基于 ...

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

    操作数据库经常使用操作就是增删查改.每做一次就写一次这些操作太麻烦,也不是必需,特别是写多条件查询并分页时.太痛苦了,所以抽出时间写了个dao帮助jar.导入即搞定!妈妈再有不用操心我的项目了! 转载 ...

  8. mybatis动态sql片段与分页,排序,传参的使用与一对多映射与resultMap使用

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-/ ...

  9. ibatis动态多条件查询及模糊查询(oracle,mysql,sql)

    首先是模糊查询的问题,开始时我使用如下条件:select * from user where name like '%#value#%'. 可是怎么也不行,好像还报错了.后来在网上找到了解决方法,就是 ...

随机推荐

  1. bsdasm

    bsdasm 来源 http://www.int80h.org/bsdasm/ Preface by G. Adam StanislavWhiz Kid Technomagic Assembly la ...

  2. Python中logging模块的基本用法

    在 PyCon 2018 上,Mario Corchero 介绍了在开发过程中如何更方便轻松地记录日志的流程. 整个演讲的内容包括: 为什么日志记录非常重要 日志记录的流程是怎样的 怎样来进行日志记录 ...

  3. SQL事务对并发处理的支持

    前言 继上次技术分享后,学到了关于mysql事务的许多新知识,感觉还是蛮有收获的.后来反过来想想,这些东西其实我们都接触过,最起码在自学考试的数据库系统原理那本书里面对事务的讲解,在里面就提到了事务的 ...

  4. 模板 Trie树

    模板 Trie树 code: #include <iostream> #include <cstdio> using namespace std; const int wx=2 ...

  5. 牛客寒假算法基础集训营4 F Applese 的大奖

    链接:https://ac.nowcoder.com/acm/contest/330/H来源:牛客网 Applese 和它的小伙伴参加了一个促销的抽奖活动,活动的规则如下:有一个随机数生成器,能等概率 ...

  6. kuangbin专题十二 POJ3186 Treats for the Cows (区间dp)

    Treats for the Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7949   Accepted: 42 ...

  7. Mybatis学习笔记(七) —— 关联查询

    一.一对多查询 需求:查询所有订单信息,关联查询下单用户信息. 注意:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询.如果从用户信息出发查询用户下的订单信息则 ...

  8. IP地址概念

    1.1  IP地址概念 什么是IP地址:由32位二进制数组成,划分成4组,每组八位: 为了便于人类识别记忆,IP地址表现形式为 "点分十进制" 二进制数与十进制数的转换关系:00 ...

  9. 小程序自定义modal弹窗封装实现

    前言小程序官方提供了 wx.showModal 方法,但样式比较固定,不能满足多元化需求,自定义势在必行~ 老规矩先上图 点击某个按钮,弹出 modal框,里面的内容可以自定义,可以是简单的文字提示, ...

  10. C语言指针收藏

    指针是什么 >>每一个内存单元只能同时存储一个数据,如何保证内存单元同时只能存储一个数据,可以使用编号的方式实现内存单元标记,此编号就是指针. >>指针是一个变量,指针是存放着 ...