2016-11-15 3 views
0

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?

Répondre

2

Ce que vous essayez de faire ici est de composer des expressions. Les expressions, contrairement aux délégués, sont un peu plus compliquées à composer. Here est une implémentation de la façon de composer des expressions. Une fois que vous avez cette méthode Compose vous pouvez écrire votre méthode d'extension en tant que:

public static IQueryable<T> WhereEqualIfSpecified<T>(
    this IQueryable<T> query, 
    Expression<Func<T, string>> fieldExpression, 
    string filterValue) 
{ 
    return string.IsNullOrWhiteSpace(filterValue) 
     ? query 
     : query.Where(fieldExpression.Compose(value => value == filterValue); 
} 
+0

Merci! Cela a marché, et j'ai beaucoup appris sur le travail avec les expressions. –