【发布时间】:2011-06-22 22:13:04
【问题描述】:
我正在努力为分页添加 HtmlHelper,但从性能和可维护性的角度来看,我不确定将分页代码的某些部分放在哪里合适和/或最有益的位置。
我不确定 Linq to SQL 数据操作的 Skip()、Take() 和 Count() 部分是否应该存在于存储库或控制器中。
我也不确定它们的顺序和使用位置是否会以任何方式影响性能。
根据我的理解,如果它们位于存储库中,那么它的工作方式是:
1. 我会将 pageIndex 和 pageSize 作为参数传递给存储库的方法,该方法从
2. 然后从数据库中获取完整的数据集。
3. 然后将该完整数据集的 TotalItems 计数存储在一个变量中.
4. 然后应用 Skip() 和 Take() 使数据集只保留我需要的页面。
5. 显示部分数据在视图中设置为单个页面。
根据我的理解,如果他们住在控制器中,它将是这样工作的: 1. 我将从存储库中获取完整的数据集并将其存储到控制器内部的变量中。 2. 然后获取完整数据集的 TotalItems 计数。 3. 然后应用 Skip() 和 Take() 使数据集只保留我需要的页面。 4. 在视图中将部分数据集显示为单个页面。
在控制器内部(我意识到我会在此处错误地获取页数而不是 TotalItems):
Character[] charactersToShow = charactersRepository.GetCharactersByRank(this.PageIndex, this.PageSize);
RankViewModel viewModel = new RankViewModel
{
Characters = charactersToShow,
PaginationInfo = new PaginationInfo
{
CurrentPage = this.PageIndex,
ItemsPerPage = this.PageSize,
TotalItems = charactersToShow.Count()
}
};
存储库内部:
public Character[] GetCharactersByRank(int PageIndex, int PageSize)
{
IQueryable characters = (from c in db.Characters
orderby c.Kill descending
select new Character {
CharID = c.CharID,
CharName = c.CharName,
Level = c.Level
});
characters = PageIndex > 1 ? characters.Skip((PageIndex - 1) * PageSize).Take(PageSize) : characters.Take(PageSize);
return characters.ToArray();
}
此代码是我如何实现存储库中的 Skip()、Take() 和 Count() 代码的部分示例。我实际上并没有实现获取和返回 TotalItems,因为那时我意识到我不知道放置它的正确位置。
我不确定将这些放在哪里的部分原因是我不知道 Linq to SQL 在底层是如何工作的,因此我不知道如何优化性能。我也不知道在这种情况下这是否是一个问题。
当您在 Linq to SQL 上执行 .Count() 时,它是否必须从数据库中获取所有记录? 如果我执行 .Count(),然后执行 .Skip() 和 .Take(),是否必须进行单独的查询? 在 .Skip() 和 .Take() 之前使用 .Count() 是否存在性能问题?
这是我第一次使用 ORM,所以我不确定会发生什么。我知道我可以查看 Linq to SQL 正在运行的查询,但是我觉得在这种情况下听听有经验的人会更好地利用我的时间。
我想更深入地了解这一点,任何见解将不胜感激。
【问题讨论】:
-
回答 一个 您的问题,是的 - 它确实需要进行 2 次 DB 调用。避免这种情况的唯一方法是在数据库本身中进行 100% 的分页。
标签: asp.net linq-to-sql asp.net-mvc-2 repository