我写了一个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.IEnumerable1[System.Int64], System.Collections.Generic.List
1 [System.Int64])”的概念 参数名称:arg0
我尝试将IEnumerable
更改为IAsyncEnumerable
并修改函数以使用asyn版本,但是直到出现错误(我找不到将List<long>
更改为{{ 1}}在where子句中。
我读到EF Core Async函数有一些局限性,但也许有人知道这是可以实现的,或者现在我应该离开并坚持使用同步解决方案?
答案 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))