小巧玲珑的通用分页

Generic pagination with the dapper

我正在使用 dapper,而且 dapper.contrib.My 问题是如何创建通用分页 class。 这是我到目前为止尝试过的方法。

 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 名称相同的 class 的 T 名称,然后写一个名为 sql_statement 的 sql 字符串应用 pagination.later 应用此代码。

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

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

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

假设您的 table 名称 总是 将与它们各自的 class/entity 名称完全匹配,以下将为您提供分页结果(使用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;
            }
    }

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

  1. 当偏移值变得非常大时,性能可能会受到影响。
  2. 以这种方式频繁插入的分页 table 可能会导致结果重复/出现在多个页面上,因为偏移值未考虑添加到 [=34= 的新行] 自上次检索以来。

这些是否可能对您的特定情况造成问题,这些潜在的缺点,以及一些替代解决方案are outlined here