I have the object classes below. How can setup a linq query to filter the myItems
list to only return items that have ItemGroups
with a CategoryId
that is in the categories
list? So in my sample data below, I want my linq query to only return the item with ItemId = 1
since it is the only item that has an itemgroup with a CategoryId
that is in the categories
list.
I have tried the following, but that does not seem to work:
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
},
]
}
]
CodePudding user response:
You could try using Any
on ItemGroup
within the Where
predicate
myItems.Where(i => i.ItemGroups.Any(g => categories.Contains(g.CategoryId)));
CodePudding user response:
Here is an approach where Linq operations are nested one level, rather than two.
For each Item
, .IntersectBy()
is used to determine its collection of ItemGroup
s whose CategoryId
is present in categories
. If any such ItemGroup
is present, the Item
will be included.
IEnumerable<Item> filteredItems = myItems
.Where(i => i.ItemGroups
.IntersectBy(categories, gr => gr.CategoryId)
.Any());
Example fiddle here.