Alex
Alex

Reputation: 38499

Linq query collection within a collection, from another collection

I have something similar to this model:

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

  public ICollection<ProductVariation> Variations { get; set; }
}


public class ProductVariation
{
  public int VariationID { get; set; }
  public string Size { get; set; }
  public bool InStock { get; set; }
}

I have a List of Product - called "availableProducts"

List<Product> availableProducts;

I then also have a List of int - requestedVariationNumbers:

List<int> requestedVariationNumbers;

What I'm trying to do is get Products from availableProducts where the Product.Variations collection contains a VariationID that is in requestedVariationNumbers.

So far, I've got this: (Generated by ReSharper based on a series of ugly foreach statements...)

It just seems "dirty" to me...

    var result = (
      from rvn in requestedVariationNumbers
      from product in availableProducts
      from itemVariation in product.ItemVariations
      where itemVariation.ItemNo == rvn
      select product)
      .ToList();

Upvotes: 2

Views: 1001

Answers (2)

AakashM
AakashM

Reputation: 63340

An approach using Intersect :

var result = 
    from product in availableProducts
    let variationIds = from v in product.Variations select v.VariationID
    where variationIds.Intersect(requestedVariationNumbers).Any()
    select product;

You can ToList() should you need to - result here is IEnumerable<Product>.

Upvotes: 1

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174289

Try this:

var result = availableProducts.Where(p => p.Variations
                                           .Any(v => requestedVariationNumbers
                                                     .Contains(v.VariationID)));

This is not really efficient. It would be better if requestedVariationNumbers would be a HashSet, because requestedVariationNumbers.Contains(v.VariationID) is called for every variation in every product in the worst case and for every first variation of every product in the best case.

Upvotes: 5

Related Questions