entity framework异步记录计数与记录

我正在尝试从数据库中获取记录,但在同一次调用DB中获取记录计数。 我的方法是异步的,所以我不确定这是否是正确的方法:

public async Task<IEnumerable> GetAsync(int pageIndex, int pageSize) { var products = this.Repository.GetAll().OrderBy(p => p.Price).AsQueryable(); var count = await products.CountAsync(); if (count == 0) return new List(); products = products.ToPaginatedList(pageIndex, pageSize); var result = await products.ToListAsync(); var viewModels = new List(); Mapper.Map(result, viewModels); return viewModels.AsEnumerable(); } 

我认为等待CountAsync()不太好,但我不确定如何实现它。

问候。

编辑:

我为没有在任何地方返回计数而道歉,因为它现在看起来我只计算因为== 0检查,但我最终将返回计数记录,因为我需要它为我的角度分页指令。 还没弄明白我将如何返回(新类vs元组)所以我错过了它并专注于单个数据库调用中的entity frameworkCount()和实体提取。

我认为您的代码可以针对此进行优化:

 using AutoMapper.QueryableExtensions; //... public async Task> GetAsync(int pageIndex, int pageSize) { var products = this.Repository.GetAll().OrderBy(p => p.Price);// I think you don't need to call AsQueryable(), you already are working with IQueryable var result=await products.Skip(pageIndex*pageSize).Take(pageSize).ProjectTo().ToListAsync(); return result; } 

最后,它可以在一行中完成:

 public async Task> GetAsync(int pageIndex, int pageSize) { return await this.Repository.GetAll() .OrderBy(p => p.Price) .Skip(pageIndex*pageSize) .Take(pageSize) .ProjectTo() .ToListAsync(); } 

.ProjectTo()将告诉AutoMapper的映射引擎向IQueryable发出一个select子句,该子句将通知Entity Framework它只需要查询您映射的属性,就像手动将IQueryable手动投影到ProductItemViewModel 。一个Select子句。

糟糕,我完全错过了你的回归类型。 我以为您使用计数来显示TotalResultCount以及您的分页集合。 既然你不是,那就完全消除了。

只需删除CountAsync()调用,并将results.Count属性检查为零。 这不是你拥有的结果总数,但它会告诉你它是否为空。

 public async Task> GetAsync(int pageIndex, int pageSize) { var result = await this.Repository.GetAll() .OrderBy(p => p.Price) .ToPaginatedList(pageIndex, pageSize) .ToListAsync(); if (result.Count == 0) { // This "if" really isn't necessary, as your mapper should map an // empty collection to an empty collection. But it is a minor // efficiency improvement, and it speaks to your original code. return Enumerable.Empty(); } var viewModels = new List(); Mapper.Map(result, viewModels); return viewModels; // AsEnumerable() has no effect here, as the cast will happen by // default anyway } 

这避免了对服务器的额外调用,代价是该变量的含义。 如果你的分页支持告诉用户代理有多少页面,请阅读下面的这一行,但除此之外,这段代码应该处理你在这里做的事情。


这个答案有一个错误的假设,你需要知道总结果数; 我最初错误地读了代码。

听起来你所拥有的将是你最好的选择。

我不知道entity framework中有什么方法可以使用T-SQL的COUNT(*) OVER ()子句,这听起来就像你正在寻找的那样。

您的方法唯一的问题是您将针对您的服务器运行两个查询:

  • 有多少条记录?
  • 给我记录x..y

这比你可以一起抓住它们效率低,但它可能不会在大多数应用程序中产生巨大的差异。 如果您担心性能成本,我会重新评估您可能拥有的索引,或者甚至考虑entity framework的替代方案。

事实上,这都是async并没有任何区别。 调用await CountAsync()正是它的用法。