En passant dans un lambda à une déclaration où
-
14-10-2019 - |
Question
Je remarque aujourd'hui que si je fais ceci:
var items = context.items.Where(i => i.Property < 2);
items = items.Where(i => i.Property > 4);
Une fois que j'accéder aux éléments var, il exécute uniquement la première ligne que l'appel de données et fait alors le deuxième appel à la mémoire. Cependant, si je fais ceci:
var items = context.items.Where(i => i.Property < 2).Where(i => i.Property > 4);
je reçois une seule expression, exécutée dans le contexte qui comprend les deux déclarations où. J'ai une foule de variables que je veux utiliser pour construire l'expression pour le lambda LINQ, mais leur présence ou l'absence des changements de l'expression telle que je devrais avoir un certain nombre de rediculous conditionals pour satisfaire tous les cas. Je pensais que je pouvais ajouter les déclarations where () comme dans mon premier exemple ci-dessus, mais qui ne se termine pas en une seule expression qui contient tous les critères. Par conséquent, je suis en train de créer juste le lambda lui-même en tant que tel:
//bogus syntax
if (var1 == "something")
var expression = Expression<Func<item, bool>>(i => i.Property == "Something);
if (var2 == "somethingElse")
expression = expression.Where(i => i.Property2 == "SomethingElse");
Et puis passer que pour l'où de mes context.Items à évaluer. A) est ce droit, et B) si oui, comment faites-vous?
EDIT:
IQueryable assessments = assessmentContext.Assessments;
metAssessments = metAssessments.Take(pageSize);
résultats dans
SELECT [Fields] <== edited
FROM [dbo].[Assessment] AS [t0]
INNER JOIN [dbo].[AssessmentComment] AS [t1] ON [t1].[ID] = [t0].[AssessmentID] <== because of load options
Pourquoi pas top x (comme représenté par pageSize)?
La solution
Quel fournisseur de requête utilisez-vous? Pour tout fournisseur raisonnable, votre premier exemple doit exécuter sur la source (pas en mémoire) que la conjonction des deux conditions dans chacune de vos Where
s.
En ce qui concerne votre question, non, ce n'est pas la bonne façon de procéder à la construction d'un Expression
manuellement. Votre première définition est très bien, mais de construire une conjonction vous devez utiliser Expression.AndAlso
.
ont déjà enveloppé cela dans une bibliothèque pour votre utilisation. Voir PredicateBuilder .
Autres conseils
Utilisez le PredicateBuilder pour construire votre requête dynamiquement.
Je suppose que la raison pour laquelle la première et la deuxième diffèrent que items
a déjà accédé à des données à ce moment-là. Si vous faites l'objet de items
Hériter IQueryable
vous n'exécuter quoi que ce soit contre le contexte que vous accédez réellement les éléments de la collection.