我是EF和LINQ的初学者,我想按产品ID检索一个类别列表(带过滤器)。
所以,我在Product * <---> * Category
之间有多对多关系,我使用以下代码:
var categList = dbContext.Products
.Where(prod => prod.PROD_UID == 1234)
.SelectMany(prod => prod.Categories)
.Distinct();
categList = SearchCategories(filter, categList);
categList = SortCategories(filter, categList);
categList = PageCategories(filter, categList);
其中SearchCategories
用于重用某些代码,如下所示
IQueryable<Category> SearchCategories(MyFilter filter, IQueryable<Category> source = null)
{
source = source ?? this.dbContext.Categories;
return source.Where(cat => [...filtering...] );
}
虽然这看起来不错,但我希望稍微优化一下,在SelectMany
内部进行过滤(在SearchCategories
内使用SelectMany
)...但我无法做到工作。我试过这个,但给了我错误
var categList = dbContext.Products
.Where(prod => prod.PROD_UID == 1234)
.SelectMany(cat => SearchCategories(filter, prod.Categories.AsQueryable()).AsEnumerable());
// throws LINQ to Entities does not recognize the method 'SearchCategories'
如何过滤SelectMany
内的类别?
谢谢!
答案 0 :(得分:1)
您的问题是您将服务器查询与客户端查询混淆,这里没有任何魔力。
您的第一个查询,直到Distinct被序列化并发送到服务器,然后服务器发送响应,然后您在客户端中运行过滤器。
当您将SearchCategories
放入服务器查询时,它无法解析,因此您会收到错误。
你有两个选择:
1:只需在第一个查询中写出SearchCategories
的所有查询,使其在服务器中运行
.SelectMany(prod => prod.Categories.Where(c => [...filtering...]))
记住过滤不能调用客户端代码。
2:您放置了ToList或ToArray,然后使用SearchCategories
,但此选项不会优化任何内容。