Linq 如何根据嵌套列表 属性 和外部列表的重叠过滤对象列表

Linq how to filter an object list based on overlap of nested list property and external list

我有下面的对象类。如何设置 linq 查询以将 myItems 列表过滤为仅具有 ItemGroupsCategoryId 位于 categories 列表中的 return 项?因此,在下面的示例数据中,我希望我的 linq 查询仅 return 具有 ItemId = 1 的项目,因为它是唯一具有 CategoryId 的项目组的项目,该项目组位于 categories列表。

我尝试了以下方法,但似乎不起作用:

myItems.Where(i => categories.Contains(i.ItemGroups.Select(g => g.CategoryId)))
public ItemGroup{
    int ItemGroupId
    int CategoryId
}

public class Item(
    int ItemId;
    List<ItemGroup> ItemGroups
)

List<int> categories {2,5,7}
List<Item> myItems = [
    {
        ItemId = 1,
        ItemGroups = [
            {
                ItemGroupId = 1,
                CategoryId = 1
            },
            {
                ItemGroupId = 2,
                CategoryId = 2
            },
        ]
    },
    {
        ItemId = 2,
        ItemGroups = [
            {
                ItemGroupId = 3,
                CategoryId = 3
            },
            {
                ItemGroupId = 4,
                CategoryId = 4
            },
        ]
    }
]

您可以尝试在 Where 谓词

中对 ItemGroup 使用 Any
myItems.Where(i => i.ItemGroups.Any(g => categories.Contains(g.CategoryId)));

这是一种将 Linq 操作嵌套一层而不是两层的方法。

对于每个 Item.IntersectBy() 用于确定其 ItemGroup 的集合,其 CategoryId 出现在 categories 中。如果存在任何此类 ItemGroup,则将包括 Item

IEnumerable<Item> filteredItems = myItems
    .Where(i => i.ItemGroups
        .IntersectBy(categories, gr => gr.CategoryId)
        .Any());

示例 fiddle here.