在实体框架中,使用LINQ to Entities,数据库分页通常以下列方式完成:
int totalRecords = EntityContext.Context.UserSet.Count;
var list = EntityContext.Context.UserSet
.Skip(startingRecordNumber)
.Take(pageSize)
.ToList();
Run Code Online (Sandbox Code Playgroud)
这导致两个数据库调用.
请告诉我,如何将其减少到一个数据库调用.
谢谢.
我首先使用EF4代码,并拥有持久性存储库和与之交互的服务层.我有一个服务层方法,它在我的存储库上调用IQueryable方法并返回包含实体的IEnumerable.我还需要返回总记录数,以便我可以计算分页链接.
我应该如何从我的服务方法返回int和IEnumerable?
所有这些都应该有效,但哪一个最干净?
更新: 这是对架构的一些澄清.如果这是错误的,请告诉我更好的方法(例如 - 在表示层而不是服务层进行分页等)
回购层:
返回DbSet的IQueryable,从表示层抽象出db访问
服务层:
对IQueryable执行LINQ查询以进行过滤,并根据需要使用skip和take获取页面项并返回IEnumerable(返回时也设置为List以避免任何DbContext生命周期问题)
表示层:
在Service层上调用该方法(getPagedResults(filters,pageNumber,pageSize))
从它的外观来看,我还需要添加一个单独的方法来获得总结果.希望能在一个电话中完成这一切.
我宁愿不将所有记录带回演示文稿,然后页面......似乎效率低下.
我在 Linq to Entities 驱动的数据访问层中有一个数据调用,该层旨在进行分页调用。
这样做时,我需要选择数据的一个子集,比如 50 行,但还要获取所有匹配项的计数,以了解要分页的总匹配项数。
目前,我正在做以下事情:
var queryResult = DatabaseContext.Table
.Where(x => !x.IsDeleted)
.Where(p => (
p.PropertyOne.ToLower().Contains(query) ||
p.PropertyTwo.ToLower().Contains(query)
));
int count = queryResult.Count();
var returnData = queryResult
.OrderBy(i => i.ID)
.Skip(start).Take((length))
.Select(y => new ObjectDTO
{
PropertyOne = y.PropertyOne,
PropertyTwo = y.PropertyTwo
}
.AsEnumerable();
Run Code Online (Sandbox Code Playgroud)
这会导致两个代价高昂的数据库操作。由于COUNT某种原因,操作实际上比SELECT操作花费的时间更长。
有没有办法在同一个操作中获得计数和子集?
我的逻辑流程说我们执行以下操作:
这在一次操作中似乎是可能的,但我不知道如何进行。
尝试一,更慢
尝试了 D Stanley 将完整结果集转换为 aList并在分页中进行计数和内存的建议,但它大约慢了 2 倍(平均 6.9 秒与平均 3.9 秒)
值得一提的是,数据集大约有 25,000 条记录,在 JOIN 中搜索了十多个相关表。