title: Check if a collection contains ALL values from another collection with Deferred Execution
body: <p>Consider the following classes:</p>
  
  <pre><code>public class Recipe
  {
      public string Id { get; set; }
      public ICollection&lt;RecipeFacet&gt; RecipeFacets { get; set; }
  }
  
  public class RecipeFacet
  {
      public string Id { get; set; }
      public Facet Facet { get; set; }
      public string RecipeId { get; set; }
  }
  
  public class Facet
  {
      public string Name { get; set; }
  }
  </code></pre>
  
  <p>I need to improve an existing query. I was thinking of using Linq's deferred execution. How would I write a Linq query that returns only <code>Recipes</code>, that contains ALL <code>Facets</code> I specify in a list of <code>Tuples</code>?</p>
  
  <p>This is the original code that loops through <code>Recipes</code> and its <code>Facets</code>.  It works but it is slow if my intial <code>results</code> query has lots of <code>Recipes</code>.</p>
  
  <pre><code>IQueryable&lt;Recipe&gt; result; //assume we have data here
  
  string query = "Cuisine:American+Recipe-Type:dinners";
  IEnumerable&lt;Tuple&lt;string, string&gt;&gt; taxFacets = query
              .Split(' ')
              .Select(tf =&gt; tf.Split(':'))
              .Select(tf =&gt; new Tuple&lt;string, string&gt;(tf[0], tf[1]))
              .Distinct();
  
  var recipeFacetCollection = result.Select(r =&gt; r.RecipeFacets).ToList();
  var matchedRecipesIds = new List&lt;string&gt;();
  
  var recIds = result.Select(r =&gt; r.Id).ToList();
  
  // initially, include all recipes
  matchedRecipesIds.AddRange(recIds);
  
  // loop through each recipe's facet collection
  foreach (var col in recipeFacetCollection)
  {
      // loop through the tax facets from the query
      foreach (var tf in taxFacets)
      {
          var exists = col.Any(f =&gt; f.Facet.Name.Equals(tf.Item2, StringComparison.OrdinalIgnoreCase));
          // remove any recipe that is missing a facet
          if (!exists)
          {
              matchedRecipesIds.Remove(col.First().RecipeId);
          }
      }
  }
  
  result = result.Where(r =&gt; matchedRecipesIds.Contains(r.Id));
  </code></pre>
  
  <p>How can I have a nice Linq query with deferred execution?</p>
  
  <p><strong>UPDATE::</strong></p>
  
  <p>Turning my Tuple into a List allows me to do this. But this query doesn't return any of my records. </p>
  
  <p>This is my criteria:</p>
  
  <p><code>Recipes</code>, that have a collection of <code>RecipeFacts</code>, that contains <code>Facets</code> that have Name = "American" AND Name = "dinners".</p>
  
  <pre><code>var listFacets = new List&lt;string&gt;()
  {
      "American",
      "dinners"
  };
  
   result = result
        .Where(r =&gt; r.RecipeFacets
        .All(f =&gt; !listFacets.Any(t =&gt; t.Equals(f.Facet.Name, StringComparison.OrdinalIgnoreCase))));
  </code></pre>