«Ou» équivalent dans l'expression lambda Linq Where ()

91

Existe-t-il une méthode dans Linq où vous pouvez utiliser pour créer des chaînes SQL comme "... where (a = 1) OR (a = 2)"?

dstr
la source
4
Je suppose que vous savez comment utiliser ||et que vous voulez quelque chose de dynamique, comme a=a.where(hour=> hour<20); if(weekend) a=a.where(hour=> hour>6);. Vous voudrez peut-être le dire plus clairement ...
Kobi

Réponses:

189

Vous pouvez certainement le faire dans une clause Where (méthode d'extension). Si vous avez besoin de créer dynamiquement une requête complexe, vous pouvez utiliser un PredicateBuilder .

 var query = collection.Where( c => c.A == 1 || c.B == 2 );

Ou en utilisant un PredicateBuilder

 var predicate = PredicateBuilder.False<Foo>();
 predicate = predicate.Or( f => f.A == 1 );
 if (allowB)
 {
    predicate = predicate.Or( f => f.B == 1 );
 }

 var query = collection.Where( predicate );
Tvanfosson
la source
Cela a très bien fonctionné car j'avais besoin de construire mon Ou en fonction des valeurs des paramètres entrants - Génial!
Mark le
Très cool. C'est dommage que cela ne soit pas inclus en tant que fonction à l'intérieur de .NET en standard.
maxp
1
Très belle implémentation, même si cela n'a peut-être pas été noté, cela ne fonctionne que pour C # 5+.
Thomas.Donnelly
25

Vous pouvez utiliser les opérateurs booléens .NET standard dans votre clause where unique:

MyDataSource.Where(data => data.a == 'a' || data.a == 'b')
Simon Steele
la source
19

Vous utilisez tous les mêmes opérateurs que dans C normal # ===> || pour "ou" && pour "et" etc.

var something = from s in mycollection
                where s.something == 32 || 
                      s.somethingelse == 45 
                select s
Muad'Dib
la source
1

dans votre .Where()appel utiliser l' opérateur booléen standard « ou » opérateur ||.

var query = items.Where(item => (item == 1 || item == 2));

Tout ce que fait l'appel Where est une comparaison booléenne sur tout ce que vous voulez, vous pouvez donc le remplir avec autant de logique conditionnelle que vous le souhaitez.

Alastair Pitts
la source
0

Si vous ne connaissez pas le nombre de paramètres, vous pouvez utiliser ceci:

Exemple de données

var parameters= new List<string>{"a","d"};
var sampledata = new Dictionary<string,string>();
    sampledata["a"] = "A";
    sampledata["b"] = "B";
    sampledata["c"] = "C";
    sampledata["d"] = "D";

Code

var query = sampledata.AsQueryable();
var firstItemKey = sampledata.FirstOrDefault().Key;
var queryresult= sampledata.Where(x => x.Key == firstItemKey).AsQueryable();
foreach (var parameter in parameters.Skip(1))
{
    queryresult=queryresult.Concat(query.Where(x => x.Key == parameter));
}
var result = queryresult.ToList();
Bora Aydın
la source
-1

Ceci est intégré dans .net maintenant, je ne sais pas si ce n'était pas le cas auparavant. Étant donné une requête Linq existante, vous pouvez ajouter une clause where qui prend un tableau de chaînes (SearchStrings) et vérifier si l'une d'entre elles correspond à n'importe quel objet de la collection que vous recherchez. L'utilisation de ToLower () garantit simplement que vous évitez le respect de la casse dans les requêtes SQL.

query.Where(i => SearchStrings.Any(s => i.ToLower().Contains(s.ToLower()));

Vous pouvez faire la même chose pour un prédicat «et» en faisant correspondre tous les mots du tableau à l'objet de la collection.

query.Where(i => SearchStrings.All(s => i.ToLower().Contains(s.ToLower()));

Dans cet exemple, i correspond à chaque objet d'une collection et s correspond à chaque chaîne du tableau SearchStrings.

JMacor
la source
1
Notez que «Any» ne peut pas être traduit par un fournisseur EF et sera évalué localement, ce qui entraînera une analyse complète de la table et un filtrage en mémoire.
Wade Bee