Je rencontre souvent, dans LINQ pour Entity Framework, un modèle où ajouter une clause .Where
si une valeur de chaîne est spécifiée, comme:Comment puis-je construire une logique sur la logique fournie dans une expression LINQ-to-Entities Where?
IQueryable<Foo> query = Foos.AsQueryable()
if (!string.IsNullOrWhitespace(nameFilter)) query = query.Where(x => x.Name == name);
if (!string.IsNullOrWhitespace(addressFilter) != null) query = query.Where(x => x.Address == addressFilter);
if (!string.IsNullOrWhitespace(cityFilter) != null) query = query.Where(x => x.City == cityFilter);
// ...
Je voulais nettoyer ce et éviter de répéter le filtre. Je pensais que je pouvais créer une méthode d'extension:
public static IQueryable<T> WhereEqualIfSpecified<T>(
this IQueryable<T> query,
Expression<Func<T, string>> fieldDelegate,
string filterValue)
{
return string.IsNullOrWhiteSpace(filterValue)
? query
: query.Where(x => fieldDelegate(x) == filterValue); // not valid, see question below
}
Alors que je peux plutôt changer mon code pour:
IQueryable<Foo> query = Foos.AsQueryable()
.WhereEqualIfSpecified(x => x.Name, nameFilter)
.WhereEqualIfSpecified(x => x.Address, addressFilter)
.WhereEqualIfSpecified(x => x.City, cityFilter)
// ...
;
Mais je trouve que, dans la méthode WhereEqualIfSpecified
ci-dessus, fieldDelegate
doit être compilé à un Func()
être invoqué contre la source de l'entité, ce qui ruine le point de faire ces étapes, qui seraient exécutées dans la base de données dans mon code d'origine.
Il me manque la dernière étape de la façon de créer un nouveau Expression
de fieldDelegate
qui peut faire une comparaison, plutôt que de simplement retourner la valeur de la chaîne. Cette approche fonctionnera-t-elle? Comment puis-je créer les Expression
nécessaires dans WhereEqualIfSpecified
pour permettre à LINQ-to-Entities de l'exécuter plus tard?
Merci! Cela a marché, et j'ai beaucoup appris sur le travail avec les expressions. –