2016-03-01 22 views
5

Credo che ci sia un modo migliore per scrivere questo, ma sto vivendo un blocco mentale.Espressione lambda con operatore OR

int num = 0; 

using(var db = new TestDB()) 
{ 
    num = db.Table.Where(x => x.FavoriteSport == "Baseball" && 
          (x.FavoriteColor == "Green" || 
           x.FavoriteColor == "Blue" || 
           x.FavoriteColor == "Red")).Count(); 
} 

return num; 

C'è un modo migliore per scrivere i OR affermazioni? Ho provato:

x.FavoriteColor == "Green" || "Blue" || "Red" 

ma il compilatore dice Operator || cannot be applied to operands of type 'bool' and 'string'

Ogni aiuto è apprezzato.

+1

Go per migliorare la leggibilità. Credo che il tuo esempio attuale sia leggibile e mantenibile. Non c'è niente di sbagliato in questo. Prendi nota se non c'è niente tra l'uso di 'e' l'istruzione' return' puoi semplicemente fare 'return db.Table.Where ...' – Default

+0

Grazie a tutti per i commenti e le risposte veloci. Non mi aspettavo che tutte quelle risposte accadessero così rapidamente ahah, ma immagino che questo sia il motivo per cui SO è il numero 1. @ Default Grazie per la nota. Sarò sicuro di usarlo. Grazie ancora –

+0

@Servy buon punto, mi sono perso. Rimosso il commento per evitare confusione –

risposta

6

È possibile utilizzare il metodo Contains di array/elenco/hashset.

var colors = new List<string> {"Green", "Red", "Blue" }; 

db.Table.Where(x => x.FavoriteSport == "Baseball" && 
         (colors.Contains (x.FavoriteColor)).Count() 

Si genererà query SQL come

SELECT ... WHERE FavoriteColor = 'Baseball' AND FavoriteColor in ("Green", "Red", "Blue") 

mi piacerebbe aggiungere che se si lavora con i set di dati che vengono memorizzati in una memoria che si dovrebbe tenere a mente che la lista di Contains prende O (N) iterazione per ottenere risultati. Quindi se colors contiene molti elementi dovresti usare il set HashSet invece con O (1).

var colors = new HashSet<string> {"Green", "Red", "Blue", .... }; 

someDataSet.Where(x => x.FavoriteSport == "Baseball" && 
         (colors.Contains (x.FavoriteColor)).Count() 

È possibile trovare l'elenco-HashSet confronto delle prestazioni here

+0

Mostra sempre l'esempio migliore prima IMO. Non è necessario modificare fino alla fine della risposta. – Default

+2

Per curiosità, un hashset avrebbe un incremento delle prestazioni? Questa è una query al database, che viene convertita in SQL dinamico, quindi dovrebbe comunque scorrere l'intera collezione. –

+1

@Valentin Ok, sono d'accordo nella memoria, una ricerca attraverso un hashset è più efficiente (a volte). Il punto che sto facendo è che questo comando dovrebbe generare SQL (cioè, OP sta usando EF). La query generata dovrebbe essere "SELEZIONA ... WHERE FavoriteSport =" Baseball "AND FavoriteColor IN ( Rosso", "Blu", "Verde"). Dovrebbe scorrere l'intera collezione per generare l'istruzione IN. –

4
string[] FavColor = new string[]{"Green","Red","Blue"}; 

int num = 0; 

    using(var db = new TestDB()) 
    { 
     num = db.Table.Where(x => x.FavoriteSport == "Baseball" &&FavColor.Any(x.FavoriteSport)).Count(); 
    } 

    return num; 
3

È possibile utilizzare un contenitore di oggetti e utilizzare il metodo contiene. Ad esempio:

Vorrei controllare un profilo per assicurarmi che l'SQL generato stia usando l'istruzione IN però.

3

praticamente tutto ciò che hanno detto: è possibile creare una raccolta di stringhe valide e verificare se la stringa è in quella raccolta. Si può fare in linea:

num = db.Table.Count(x => x.FavoriteSport == "Baseball" && 
         new []{"Green","Red","Blue"}.Contains(x.FavoriteColor); 

Da segnalare che è possibile scambiare il vostro Where per Count direttamente