Question

I have two SQL tables: Movies and Tags, while Movies contains a List<Tag>

Now I want to find all movies that have at least one of the tags of a List<Tag> argument. How can I do that in LINQ?

public IEnumerable<Group<Genre, Movie>> GetMoviesGrouped(string search, List<Tag> tags)
{
    var movies = from movie in Movies
    where ( movie.Name.Contains(search)) && movie.Tags.???contains any element of tags???
    group movie by movie.genre into g
    select new Group<Genre, Movie> { Key = g.Key, Values = g };
....
}
Was it helpful?

Solution

Movies where any of the tags is contains in tags:

var movies = from movie in Movies
             where ( movie.Name.Contains(search)) 
                  && movie.Tags.Any(t => tags.Contains(t))
             group movie by movie.genre into g
             select new Group<Genre, Movie> { Key = g.Key, Values = g };

However since this is comparing Tag instances and not strings:

  1. It probably won't get translated to SQL (which means you will have to hydrate the query and do the extra filtering in Linq-to-Objects), and
  2. You may want to compare the data of the tags rather than instances (unless you have overridden Equals on Tag

something like:

where movie.Tags.Any(mt => tags.Any(t => t.ID == mt.ID))   // or whatever property(ies) of `Tag` defines equality

OTHER TIPS

You can intersect both list and see if there is any element like:

&& movie.Tags.Intersect(tags).Any()

Since Tag is an object, It will compare the references. Instead you can select unique identifier from Tag and then intersect that like:

&& movie.Tags.Select(r=> r.ID).Intersect(tags.Select(t=> t.ID)).Any()

Where ID is the primary key of Tag table.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top