2012-05-19 23 views
81

Usando linq, ¿cómo puedo recuperar una lista de elementos donde su lista de atributos coincide con otra lista?lista de linq donde contiene cualquiera en la lista

Tome este ejemplo sencillo y pseudo código:

List<Genres> listofGenres = new List<Genre>() { "action", "comedy" }); 
var movies = _db.Movies.Where(p => p.Genres.Any() in listofGenres); 

Respuesta

154

suena como usted quiere:

var movies = _db.Movies.Where(p => p.Genres.Intersect(listOfGenres)).Any(); 

o proporcionar el predicado en la llamada Any de hacerlo todo de una sola vez:

var movies = _db.Movies.Any(p => p.Genres.Intersect(listOfGenres)); 
+0

yo estaba tratando de utilizar esta consulta para el cuadro de búsqueda, se busca en cualquier carácter en la columna person_name, tengo este error: "DbIntersectExpression requiere argumentos con ResultTypes de la colección compatible, así que probé '.StartWith, .EndsWith, .Contains' desde [aquí] (http://blogs.telerik.com/openaccessteam/posts/12-04-17/string-matching-in- linq.aspx) funciona, pero qué se puede hacer para usar su consulta – stom

+0

@stom: no tenemos información suficiente para ayudarlo con eso, debe hacer una nueva pregunta con un contexto * mucho * más. –

+0

@JonSkeet Siempre uso el método Contiene para este tipo de consultas. Sentí curiosidad al ver su respuesta y verifiqué la implementación interna y encontré que Intersect usa Set. ¿Puede decirme la diferencia de rendimiento entre esos dos métodos? – Sreejith

42

Puede usar una consulta Contains para esto:

var movies = _db.Movies.Where(p => p.Genres.Any(x => listOfGenres.Contains(x)); 
0

Supongo que esto también es posible así?

var movies = _db.Movies.TakeWhile(p => p.Genres.Any(x => listOfGenres.Contains(x)); 

¿Es "TakeWhile" peor que "Where" en sentido de rendimiento o claridad?

+0

'TakeWhile' es una función diferente: dejará de iterar cuando no encuentre una coincidencia. –

0

O como esta

class Movie 
{ 
    public string FilmName { get; set; } 
    public string Genre { get; set; } 
} 

...

var listofGenres = new List<string> { "action", "comedy" }; 

var Movies = new List<Movie> {new Movie {Genre="action", FilmName="Film1"}, 
       new Movie {Genre="comedy", FilmName="Film2"}, 
       new Movie {Genre="comedy", FilmName="Film3"}, 
       new Movie {Genre="tragedy", FilmName="Film4"}}; 

var movies = Movies.Join(listofGenres, x => x.Genre, y => y, (x, y) => x).ToList();