实体框架异步记录计数与记录

zhu*_*ber 5 c# asynchronous entity-framework count async-await

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

    public async Task<IEnumerable<ProductItemViewModel>> GetAsync(int pageIndex, int pageSize)
    {
        var products = this.Repository.GetAll<Product>().OrderBy(p => p.Price).AsQueryable();

        var count = await products.CountAsync();
        if (count == 0)
            return new List<ProductItemViewModel>();

        products = products.ToPaginatedList(pageIndex, pageSize);
        var result = await products.ToListAsync();

        var viewModels = new List<ProductItemViewModel>();
        Mapper.Map(result, viewModels);

        return viewModels.AsEnumerable();
    }
Run Code Online (Sandbox Code Playgroud)

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

问候。

编辑:

我很抱歉没有在任何地方返回计数,因为现在看起来我只是因为 == 0 检查而计数,但我最终将返回带有记录的计数,因为我需要它来用于我的角度分页指令。还没有弄清楚我将如何返回(新类与元组),所以我错过了它并专注于实体框架 Count() 和单个数据库调用中的实体获取。

Mat*_*gen 2

糟糕,我完全错过了你的返回类型。我以为您正在使用计数来显示TotalResultCount分页集合。既然你不是,那就彻底切断它。

只需挂断CountAsync()电话,然后检查results.Count属性是否为零。这不是您拥有的结果总数,但它会告诉您它是否为空。

public async Task<IEnumerable<ProductItemViewModel>> GetAsync(int pageIndex, int pageSize)
{
    var result = await this.Repository.GetAll<Product>()
        .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<ProductItemViewModel>();
    }

    var viewModels = new List<ProductItemViewModel>();
    Mapper.Map(result, viewModels);

    return viewModels; // AsEnumerable() has no effect here, as the cast will happen by
                       // default anyway
}
Run Code Online (Sandbox Code Playgroud)

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


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

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

我不知道实体框架中有什么方法可以使用 T-SQLCOUNT(*) OVER ()子句,这听起来确实是您正在寻找的。

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

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

这比将它们放在一起的效率要低,但在大多数应用程序中可能不会产生巨大的差异。如果您担心性能成本,我会重新评估您可能拥有的索引,甚至考虑实体框架的替代方案。

事实上,这一切async并没有什么区别。跟awaitCountAsync()正是它的用途。