2012-05-19 10 views
81

Uso di linq, come posso recuperare un elenco di elementi in cui l'elenco di attributi corrisponde ad un altro elenco?linq dove elenco contiene qualsiasi nella lista

Prendete questo semplice esempio e pseudo codice:

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

risposta

154

Sembra che si desidera:

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

o fornire il predicato nella chiamata Any di fare tutto in una volta sola:

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

ho cercato di utilizzare questa query per casella di ricerca, cerca qualsiasi carattere nella colonna PERSON_NAME, ho ottenuto questo errore: 'DbIntersectExpression richiede argomenti con raccolta compatibile ResultTypes 'così ho provato '.StartWith, .EndsWith, .Contains' da [qui] (http://blogs.telerik.com/openaccessteam/posts/12-04-17/string-matching-in- linq.aspx) funziona, ma cosa si può fare per utilizzare la query – stom

+0

@stom: non abbiamo abbastanza informazioni per aiutarti - dovresti fare una nuova domanda con un * lotto * più contesto. –

+0

@JonSkeet Uso sempre il metodo Contains per questo tipo di query. Ero curioso di vedere la tua risposta e ho controllato l'implementazione interna e ho scoperto che Intersect usa Set. Puoi dirmi la differenza di prestazioni tra questi due metodi? – Sreejith

42

È possibile utilizzare una query Contains per questo:

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

Immagino che questo sia possibile anche in questo modo?

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

Is "TakeWhile" peggio di "Dove" in senso di prestazioni o chiarezza?

+0

'TakeWhile' è una funzione diversa: smetterà di iterare quando non trova una corrispondenza. –

0

O come questa

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();