使用分页控制器中的Entity Framework核心从数据库中提取数据时如何节省时间?
How to save time when pulling data from DB using Entity Framework Core in controller with paging?
我的基于 Web 的应用程序在从数据库(100-200 条记录)读取数据后在启用分页的页面上显示之前性能缓慢。我遵循了 Microsoft 的示例:
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-6.0#add-paging
我发现当我的代码循环遍历数据库中的数据、处理它并将其添加到列表中时,根据我输出的执行时间,每条记录大约需要半秒,或多或少。
微软的例子是这样的:
- 拉取数据
- 处理数据取决于排序、过滤的输入
- 将return之前的数据分页到视图中显示
当数据库中有大量记录时,这听起来会导致性能问题,因为它首先提取所有内容,然后对其进行分页。
我想知道提高性能的正确方法是什么?我还应该在刷新页面或单击 previous/next 页面按钮时将数据保存在 cache/session 中以节省时间吗?
谢谢。
更新
下面是Controller中Index Action的关键部分:
public IActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
// Read all raw data from DB
var allRequests = (from r in _context.Request).ToList();
// Create the ViewModel object List
List<CreateRequestViewModel> createRequestList = new List<CreateRequestViewModel>();
foreach (Request request in allRequests)
{
CreateRequestViewModel createRequest = new CreateRequestViewModel();
createRequest.RequestId = request.RequestId;
// Some customized code to assign value to the ViewModel object's properties
// Add the ViewModel object to the List
createRequestList.Add(createRequest);
}
// Return the PaginatedList using ViewModel List created above with paging to the page.
return View(PaginatedList<CreateRequestViewModel>.CreateAsync(createRequestList.AsQueryable(), page ?? 1, pageSize));
}
public static PaginatedList<T> CreateAsync(IQueryable<T> source, int pageIndex, int pageSize)
{
var count = source.Count();
var items = source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
return new PaginatedList<T>(items, count, pageIndex, pageSize);
}
通常如果你想在服务器端分页,你必须使用从 DbSet<>
创建的 IQueryable
public IActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
var query = _context.Request.AsQueryable();
// apply filters to query
...
var result = query.Select(r => new CreateRequestViewModel
{
RequestId = r.RequestId,
// ... other fields
});
// Return the PaginatedList using ViewModel List created above with paging to the page.
return View(PaginatedList<CreateRequestViewModel>.CreateAsync(result, page ?? 1, pageSize));
}
我的基于 Web 的应用程序在从数据库(100-200 条记录)读取数据后在启用分页的页面上显示之前性能缓慢。我遵循了 Microsoft 的示例: https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-6.0#add-paging
我发现当我的代码循环遍历数据库中的数据、处理它并将其添加到列表中时,根据我输出的执行时间,每条记录大约需要半秒,或多或少。
微软的例子是这样的:
- 拉取数据
- 处理数据取决于排序、过滤的输入
- 将return之前的数据分页到视图中显示
当数据库中有大量记录时,这听起来会导致性能问题,因为它首先提取所有内容,然后对其进行分页。
我想知道提高性能的正确方法是什么?我还应该在刷新页面或单击 previous/next 页面按钮时将数据保存在 cache/session 中以节省时间吗?
谢谢。
更新
下面是Controller中Index Action的关键部分:
public IActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
// Read all raw data from DB
var allRequests = (from r in _context.Request).ToList();
// Create the ViewModel object List
List<CreateRequestViewModel> createRequestList = new List<CreateRequestViewModel>();
foreach (Request request in allRequests)
{
CreateRequestViewModel createRequest = new CreateRequestViewModel();
createRequest.RequestId = request.RequestId;
// Some customized code to assign value to the ViewModel object's properties
// Add the ViewModel object to the List
createRequestList.Add(createRequest);
}
// Return the PaginatedList using ViewModel List created above with paging to the page.
return View(PaginatedList<CreateRequestViewModel>.CreateAsync(createRequestList.AsQueryable(), page ?? 1, pageSize));
}
public static PaginatedList<T> CreateAsync(IQueryable<T> source, int pageIndex, int pageSize)
{
var count = source.Count();
var items = source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
return new PaginatedList<T>(items, count, pageIndex, pageSize);
}
通常如果你想在服务器端分页,你必须使用从 DbSet<>
IQueryable
public IActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
var query = _context.Request.AsQueryable();
// apply filters to query
...
var result = query.Select(r => new CreateRequestViewModel
{
RequestId = r.RequestId,
// ... other fields
});
// Return the PaginatedList using ViewModel List created above with paging to the page.
return View(PaginatedList<CreateRequestViewModel>.CreateAsync(result, page ?? 1, pageSize));
}