Entity Framework 分页

Entity Framework Paging

我一直在寻找代码,如果我可以在 EF 中分页大数据,例如从 1 到 100...或更多,Web 应用程序真的很慢。 我这里有代码,但我还没有找到解决方案。

我真的需要在页面中制作数据或使数据查看更快 记录多于 (1,5000,000) 条记录。 如果有人有任何 EF 分页的代码或解决方案或数据可以更快地回复我,请大家。

谢谢大家,

[代码]

var openComplaintsAssignedToOffice = individual.Office.AssignedComplaints
                                                      .ToArray()
                                                      .Where(n => n.Individuals.Any(e => e.Employed))
                                                      .ToArray() ; 

if (!complaintModel.ShowClosedComplaints)
{
    openComplaintsAssignedToOffice = openComplaintsAssignedToOffice.Where(c => c.CurrentStatus != ComplaintStatus.Closed)
                                                                   .ToArray();
}

complaintModel.OpenComplaintsAssignedToMyOffice = openComplaintsAssignedToOffice.OrderByDescending(c => c.UpdatedDateTime)
                                                                                .ToArray();
complaintModel.OpenComplaintsAssignedToMyOffice = openComplaintsAssignedToOffice.OrderByDescending(c => c.UpdatedDateTime)
                                                                                .ToArray();
return complaintModel;

您没有具体指明要在何处查找数据分页,因此为简单起见,我假设它就在这里:

individual.Office.AssignedComplaints

(不过,作为旁注,您似乎很随意地在各处插入 .ToArray()。了解这可能 极大地 影响性能强制系统加载 许多 记录到内存中,然后再对那些本可以更好地对数据源本身执行的记录执行筛选。)

您可以使用 .Skip().Take() 函数有效地对结果进行分页。例如,假设您有这些值:

var pageSize = 10;
var currentPage = 3;  // 0-indexed, of course

鉴于这些,您希望看到记录 30-39,对吗?因此,您将使用这些值来分页数据:

individual.Office.AssignedComplaints.Skip(pageSize * currentPage).Take(pageSize)

这将导致跳过前 30 条记录 (0-29) 并获取接下来的 10 条记录,而忽略其余记录。有效返回总结果集的 "page 3"。

此分页可以应用于整个表达式树中可以过滤结果集的任何位置。在排序之前或之后,.Where() 子句之前或之后,等等。根据您打算如何塑造和呈现数据,它在逻辑上属于何处完全取决于您。

通常,您将使用 Skip() and Take() 方法来处理分页数据。 Skip() 将决定有多少元素 "skip" 来定义页面的起点,Take() 将决定要抓取多少元素。

// This will skip the first 10 records and take the next 20
var page = data.Skip(10).Take(20);

考虑Deferred Execution

处理这个问题时要考虑的一个非常重要的事情是你想尽可能地推迟执行。 ToList()ToArray() 之类的方法实际上会将您的值存储在内存中,您希望避免这种情况,尤其是对于大型数据集。

如果您可以避免调用这些方法,您将确保查询本身只执行一次(因此只返回一页记录而不是整个数据集,然后在内存中分页) .

您可能会重构您的代码以使用分页,如下所示:

// Define your page size and initial page
var page = 0;
var pageSize = 20;
// Get any open complaints
var openComplaints = individual.Office.AssignedComplaints.Where(n => n.Individuals.Any(e => e.Employed));
// Determine if complaints should be shown
if (!complaintModel.ShowClosedComplaints)
{
     openComplaints = openComplaints.Where(c => c.CurrentStatus != ComplaintStatus.Closed);                                                            
}
// Finally order and page your data
return openComplaints.OrderByDescending(c => c.UpdatedDateTime)
                     .Skip(page * pageSize)
                     .Take(pageSize)
                     .ToArray();