PussInBoots
PussInBoots

Reputation: 12343

Filter on child collection using LINQ

I have these two models (a many to many relationship):

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }

    #region Navigation properties 
    public List<Category> Categories { get; set; }
    #endregion
}

public class Category
{
    public int CategoryId { get; set; }
    public string Name { get; set; }

    #region Navigation properties
    public List<Product> Products { get; set; }
    #endregion
}

Then I have this action method:

[HttpPost]
public async Task<ActionResult> FilterProducts(List<int> categoryIds)
{
    var productsViewModel = new ProductsViewModel();

    if (categoryIds != null)
    {
        var products = await db.Products
                   .AsNoTracking()
                   .Where(??????????????????????)
                   .Where(p => p.Visible == true)
                   .OrderBy(p => p.Importance)
                   .ToListAsync();

        productsViewModel.Products = products;
    }
    else { // Do something else }

    return PartialView("_ProductsPartial", productsViewModel);
}

What I would like to do is to get all the products by categoryIds using LINQ (the .Where(??????)). So each product has a list of categories. I want to get only the products that contain those categoryIds.

Not really sure how construct the LINQ query since the filtering is done on the child collection. Any ideas?

Upvotes: 1

Views: 1670

Answers (2)

Lee.O.
Lee.O.

Reputation: 73

This will return the products that have all categoryIds

Where(p => categoryIds.
         Intersect(p.Categories.Select(ctgry => ctgry.CategoryId)).
         Count() == categoryIds.Count())

(assuming categoryIds has unique elements and the elements of List Categories have unique CategoryId fields )

Upvotes: 0

Samvel Petrosov
Samvel Petrosov

Reputation: 7706

This will return you all Products which have at least one category from categoryIds

.Where(x => x.Categories.Any(y => categoryIds.Contains(y.CategoryId)));

Upvotes: 1

Related Questions