EF:如何处理多对多关系(涉及一些过滤)

本文关键字:过滤 关系 处理 EF 何处理 | 更新日期: 2023-09-27 18:28:22

我是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中进行过滤(在SelectMany中使用SearchCategories)。。。但我做不到。我试过这个,但给了我错误

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中的类别?

谢谢!

EF:如何处理多对多关系(涉及一些过滤)

您的问题是混淆了服务器查询和客户端查询——这里没有魔法。

您的第一个查询,直到Distinct被序列化并发送到服务器,然后服务器发送一个响应,然后您在客户端中运行一个筛选器。

当你把SearchCategories放在服务器查询中时,它不能被解析,所以你会得到错误。

这里有两个选项:

1:只需在第一个查询中写入来自SearchCategories的所有查询,使其在服务器中运行

 .SelectMany(prod => prod.Categories.Where(c => [...filtering...]))

记住过滤不能调用客户端代码。

2:你放了一个ToList或ToArray,然后使用SearchCategories,但这个选项不会优化任何东西。