如何在ToListAsync()中的何处使用函数

时间:2019-01-07 20:32:04

标签: c# .net-core async-await entity-framework-core ef-core-2.1

我写了一个where函数来检查产品是否具有某些功能并找到价格最高的产品。

我的简单模型如下:

 public class Product
 {
    public long ProductID { get; set; }
    [MaxLength(150)]
    public string Name { get; set; }

    public List<Functionality> Functionalities { get; set; }
    public List<Price> Prices { get; set; }
 }

 public class Functionality
 {
    public long FunctionalityID { get; set; }
    [MaxLength(150)]
    public string Name { get; set; }

    [Required]
    public long ProductID { get; set; }
    public Product Product { get; set; }
 }

 public class Price
 {
    public long PriceID { get; set; }
    public decimal Value { get; set; }

    [Required]
    public long ProductID { get; set; }
    public Product Product { get; set; }
 }

然后使用我的同步功能查找正确的产品,如下所示:

 public List<Product> GetList(ProductFiltersDto filters)
 {
    return _context.Product
        .Include(x => x.Functionality)
        .Include(x => x.Price)
        .Where(x =>
            CheckCollectionFilter(x.Functionality.Select(f => f.FunctionalityID), filters.Functionalities) &&
            CheckMaximumPrice(x.Prices , filters.MaxPrice)
         )
         .ToList();

 }

在我的where函数下面:

private bool CheckCollectionFilter<T>(IEnumerable<T> collection, List<T> filterCollection)
{
    if (filterCollection != null)
    {
        var result = true;
        foreach (var filterValue in filterCollection)
        {
            if (!collection.Contains(filterValue))
            {
                result = false;
                break;
            }
        }

        return result;
     }
     else
     {
         return true;
     }
}

private bool CheckMaximumPrice(List<Price> prices, decimal? avalibleMinPrice)
{
    return avalibleMinPrice.HasValue && prices.Count > 0 ? prices.Min(x => x.Value) <= avalibleMinPrice : true;
}

对于以上代码,一切正常。但是当我将ToList()更改为ToListAsync()时出现错误

  

类型为'System.Collections.Generic.IAsyncEnumerable 1[System.Int64]' cannot be used for parameter of type 'System.Collections.Generic.IEnumerable 1 [System.Int64]'的表达   “ Boolean CheckCollectionFilter [Int64](System.Collections.Generic.IEnumerable 1[System.Int64], System.Collections.Generic.List 1 [System.Int64])”的概念   参数名称:arg0

我尝试将IEnumerable更改为IAsyncEnumerable并修改函数以使用asyn版本,但是直到出现错误(我找不到将List<long>更改为{{ 1}}在where子句中。

我读到EF Core Async函数有一些局限性,但也许有人知道这是可以实现的,或者现在我应该离开并坚持使用同步解决方案?

1 个答案:

答案 0 :(得分:2)

IQueriable<T>移至IEnumerable<T>时,EntityFramework将在数据库服务器上到目前为止执行查询,将所有数据拉入内存,并在内存中执行其余查询。 / p>

如果要使其在数据库服务器中运行,则必须使查询保持IQueriable<T>并使用表达式树而不是可执行代码。

您将需要提出这样的建议:

private Expression<Func<T, bool>> CheckCollectionFilter<T>(IEnumerable<T> filterCollection);

private Expression<Func<T, bool>> CheckMaximumPrice<T>(decimal? avalibleMinPrice);

并将您的查询更改为:

_context.Product
    .Include(x => x.Functionality)
    .Include(x => x.Price)
    .Where(CheckCollectionFilter(filters.Functionalities))
    .Where(CheckMaximumPrice(filters.MaxPrice))