与小巧玲珑的通用分页

时间:2015-09-11 12:26:50

标签: asp.net-mvc generics pagination dapper

我正在使用dapper和dapper.contrib。我的问题是我如何创建一个通用的分页类。 这是我到目前为止所尝试的内容。

 public class GenericRepository<T> :IGenericRepository<T> where T : class
    {
    public  async Task<IEnumerable<T>> GetAllPagedAsync(int limit,int offset)
        {
            var list = await Connection.GetAllAsync<T>();//but this return IEnumarable
            return list;

        }
}

我在想的是获取与Table名称相同的类的T名称,并编写一个名为sql_statement的sql字符串,这是应用pagination.later应用此代码。

 var list = await Connection.QueryAsync<T>("sql_statement")

这有意义吗?我有更好的方法来实现这一目标。

1 个答案:

答案 0 :(得分:1)

目前看起来好像您计划检索表中的所有行,然后从中选择您实际需要的数据页。直接从数据库中选择您需要的页面可能会更快,除非您出于某种原因确实需要所有行。

假设您的表名始终与其各自的类/实体名称完全匹配,以下内容将为您提供分页结果(使用postgres):

public class GenericRepository<T> : IGenericRepository<T> where T : class
        {
        public async Task<IEnumerable<T>> GetAllPagedAsync(int limit, int offset)
            {
                var tableName = typeof(T).Name;             
                // assuming here you want the newest rows first, and column name is "created_date"
                // may also wish to specify the exact columns needed, rather than *
                var query = "SELECT * FROM @TableName ORDER BY created_date DESC Limit @Limit Offset @Offset";
                var results = Connection.QueryAsync<T>(query, new {Limit = limit, Offset = offset});
                return results;
            }
    }

关于此的说明。我显然不熟悉数据库的结构或大小,但是对于大多数一般用途,此处显示的限制/偏移方法很可能就足够了。但是,您可能希望考虑一些潜在的问题:

  1. 当偏移值变得非常大时,性能可能会受到影响。
  2. 以这种方式对具有高频率插入的表进行分页可能会导致结果重复/出现在多个页面上,因为偏移值不会考虑自上次检索以来添加到表中的新行。
  3. 这些是否可能导致您的特定情况出现问题,这些潜在的缺点,以及一些替代解决方案are outlined here