[英]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.