Contains at least everything in the entity structure

I have the following 2 entities in my db.

public class Article { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } // Some code removed for brevity public virtual ICollection<Tag> Tags { get; set; } } public class Tag { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } // Some code removed for brevity public virtual ICollection<Article> Articles { get; set; } } 

I need to filter these articles based on the tag identifiers that are passed to my action.

 public ActionResult FindAll(List<int> tags) { // // I need to return all articles which have ALL the tags passed into this method // var query = ApplicationDbContext.Articles... } 

For example, if I submitted to 1, 2, 3 in action, only those articles that had these 3 tags or more will be returned.

How can i achieve this?

Thanks for the great answer!

All your answers gave the correct result, so I did a quick, basic profiling in sql, and these were the results based on your queries.

Query Results

+5
source share
6 answers

Use Except () and Any () , e.g.

 ApplicationDbContext .Articles .Where(a => tags.Except( a.Tags.Select( t => t.Id ).ToList() ).Any() == false) 

Except() will provide you with items from the first list that do not exist in the second list

The Except statement creates the specified difference between two sequences. It will only return elements in the first sequence that are not displayed per second.

+3
source

This should do it:

 ApplicationDbContext.Articles.Where(a => tags.All(t => a.Tags.Any(at => at.Id == t))); 
+2
source

Try the following:

  var query =from a in ApplicationDbContext.Articles where a.Tags.Count(t => tags.Contains(t.Id)) == tags.Count select a; 
+2
source

Iteratively plotting the result through IQueryable.

 public ActionResult FindAll(List<int> tags) { var queryable = ApplicationDbContext.Articles.AsQueryable(); foreach(var t in tags) { queryable = queryable.Where(w => w.Tags.Any(a => a.Id == t)); } queryable.AsEnumerable(); // stuff this into a viewmodel and return actionresult? } 
+1
source

How about this?

 var articles = ApplicationDbContext.Articles.Where (a => a.Tags.Select (t => t.Id).Intersect(tags).Count()>=tags.Count); 
+1
source

Use this:

 ApplicationDbContext.Articles.Where(a => tags.All(t => a.Tags.Contains(t))); 
0
source

All Articles