繁体   English   中英

C# 实体框架分页

[英]C# Entity Framework Pagination

有没有办法获得复杂的 Linq 查询的行数和数百万条记录,而无需两次访问数据库或编写 2 个单独的查询?

我可能有我自己的建议。 编写一个存储过程,但我擅长 MySQL 而不是 MSSQL。

任何更好的建议都会很棒。 另外,如果有人知道 Microsoft 是否正在努力将此功能添加到实体框架中。

我建议使用 Take() 函数。 这可用于指定从 linq 查询或列表中获取的记录数。 例如

List<customers> _customers = (from a in db.customers select a).ToList();
var _dataToWebPage = _customers.Take(50);

我在 MVC 应用程序中使用了类似的技术,我将 _customers 列表写入会话,然后在用户单击第 2、3 页等时使用此列表进行进一步的分页查询。这可以节省多个数据库命中。 但是,如果您的列表非常大,那么也将其写入会话可能不是一个好主意。

对于分页,您可以一起使用 Skip() 和 Take() 函数。 例如获取数据的第 2 页:

var _dataToWebPage = _customers.Skip(50).Take(50);

我最近受到(复制自)这篇代码项目文章实体框架分页的启发

代码:

public async Task<IList<SavedSearch>> FindAllSavedSearches(int page, int limit)
{
    if (page == 0)
        page = 1;

    if (limit == 0)
        limit = int.MaxValue;

    var skip = (page - 1) * limit;

    var savedSearches = _databaseContext.SavedSearches.Skip(skip).Take(limit).Include(x => x.Parameters);
    return await savedSearches.ToArrayAsync();
}

我对实体框架没有经验,也没有测试过它的性能,所以请谨慎使用:)

显示数百万条记录的常用方法就是不显示所有页面。 想一想:如果您有数百万条记录,比如每页 20 甚至 100 个项目,那么您将拥有数万页。 将它们全部展示是没有意义的。 您可以简单地加载当前页面并提供指向下一页的链接,就是这样。 或者你可以加载 100-500 条记录,但仍然只显示一个页面,并使用加载的记录信息为前几页生成页面链接(所以要确定有多少下一页可用)。

在 sql server 上很容易。 你可以写这个查询:

select count() over(), table.* from table

count () over() 将返回结果中的总行数,因此您不需要运行两个查询.. 请记住,您应该在上下文中运行原始 sql 或使用将结果作为视图模型返回的 dapper

如果您需要快速解决方案,您可以使用 XPagedList https://github.com/dncuug/X.PagedList XPagedList 是一个库,可让您轻松获取 IEnumerable/IQueryable,将其分成“页面”,并通过索引抓取特定的“页面”。 例如

var products = await _context.Products.ToPagedListAsync(pageNumber, pageSize)

我创建了一个为你做分页的 nuget 库。 https://github.com/wdunn001/EntityFrameworkPaginateCore

将 nuget 添加到项目

安装包 EntityFrameworkPaginateCore 添加

使用 EntityFrameworkPaginateCore; 给您的提供者

有 1 个方法和 2 个重载,该方法重载允许排序和过滤。 使用排序对象和过滤器对象

public async Task<Page<Example>> GetPaginatedExample(
            int pageSize = 10, 
            int currentPage = 1, 
            string searchText = "", 
            int sortBy = 2
            )
        {
            var filters = new Filters<Example>();
                filters.Add(!string.IsNullOrEmpty(searchText), x => x.Title.Contains(searchText));

            var sorts = new Sorts<Example>();
            sorts.Add(sortBy == 1, x => x.ExampleId);
            sorts.Add(sortBy == 2, x => x.Edited);
            sorts.Add(sortBy == 3, x => x.Title);

            try
            {
                return await _Context.EfExample.Select(e => _mapper.Map<Example>(e)).PaginateAsync(currentPage, pageSize, sorts, filters);
            }
            catch (Exception ex)
            {
                throw new KeyNotFoundException(ex.Message);
            }
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM