I have the following 2 entitys 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 IDs that are passed into 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 passed in 1, 2, 3 into the action, only articles which had these 3 tags or more would be returned.
How can I achieve this?
Thanks for the great response!
All your answers produced the correct result so I did some quick, basic profiling in sql and this was the results based on your queries.
Use Except() and Any() like
ApplicationDbContext
.Articles
.Where(a => tags.Except( a.Tags.Select( t => t.Id ).ToList() ).Any() == false)
Except()
will give you the items from the first list which do not exist in the second list
The Except operator produces the set difference between two sequences. It will only return elements in the first sequence that don't appear in the second.
This should do it:
ApplicationDbContext.Articles.Where(a => tags.All(t => a.Tags.Any(at => at.Id == t)));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With