2010-02-03 5 views
2

Je réfléchis à la refactorisation d'un référentiel Je dois améliorer sa flexibilité et réduire le nombre de méthodes.Référentiel prenant l'expression linq pour le filtrage

Lorsqu'il existe des méthodes suivantes:

Collection GetAllUsersByRole(Role role) 
User GetUserByuserName(string userName) 

... Je voudrais avoir une seule méthode prenant une expression Linq:

ICollection GetUsers(Expression e) 
{ 
    //retrieve user collection from store 
    //apply expression to collection and return 
} 

Est-ce une approche raisonnable? Vraisemblablement, je perdrais de l'efficacité parce que la collection complète d'utilisateurs devrait être récupérée et filtrée à chaque fois, plutôt que de récupérer un sous-ensemble d'utilisateurs selon des critères codés en dur.

Modifier: NHibernate fournit ORM dans ma mise en œuvre.

Répondre

3

Vous voulez vraiment prendre une expression comme argument de cette méthode.

En ce qui concerne les performances, tout dépend de la distance que vous souhaitez y consacrer. La méthode la plus simple consiste à mettre tous les objets en mémoire puis à filtrer avec l'expression de prédicat.

D'un autre côté, vous mentionnez une sorte de critère. Je n'ai aucune idée de ce qu'est votre système de données principal, mais vous pouvez utiliser ces filtres et les transformer en critères. C'est essentiellement ce que Linq to SQL et Linq to Entities font, mais nous espérons que la gamme de possibilités que vous avez besoin de prendre en charge est nettement plus petite. Si ce n'est pas le cas, il peut être judicieux de passer à l'un des outils ORM si vous souhaitez adopter cette approche.

+0

"La méthode la plus simple consiste à mettre tous les objets en mémoire, puis à les filtrer avec l'expression de prédicat." C'est un très bon point, cette classe peut juste être un traducteur à l'autre logique, mais réduit le nombre de méthodes exposées. –

1

Cette approche n'est pas très raisonnable, car elle vous coûtera généralement beaucoup de problèmes de performance. Si vous utilisez une technologie d'accès aux données qui accepte les requêtes LINQ, vous pouvez simplement utiliser cette requête (expression) avec celle-ci. Cela peut être IQueryable pour LINQ to SQL ou ObjectQuery pour EntityFramework. Il peut également être ICriteria (sans support linq) pour nHibernate. Tous les outils ORM modernes ont leur propre API d'expression, vous n'avez donc qu'à l'utiliser. Si vous avez une couche d'accès aux données personnalisée, vous devrez écrire votre propre API pour créer des critères, par exemple Query Object.

+0

Nous utilisons NHibernate, donc je devrais fournir un objet ICriteria au lieu d'une expression? Si c'est le cas, je serais déçu de ne pas pouvoir utiliser les expressions lambda. – Ben

+1

@Ben Aston, NHibernate a commencé à créer un fournisseur Linq complet (http://sourceforge.net/projects/nhibernate/files/), mais je ne sais pas quel est le niveau de support actuel. Comme je l'ai mentionné dans ma réponse, vous pouvez transformer l'expression de filtre en critères Hibernate, mais vous pouvez restreindre les types de requêtes que vous pouvez exécuter de cette façon (l'égalité simple d'une propriété par exemple sera probablement facile). –

Questions connexes