J'essaie de décider du meilleur modèle pour l'accès aux données dans mon application MVC. Actuellement, après avoir suivi la série de vitrines MVC, j'utilise des référentiels, exposant IQueryable à une couche de service, qui applique ensuite des filtres. Initialement, j'ai utilisé LINQtoSQL par exemple.Les référentiels doivent-ils exposer IQueryable à la couche de service ou effectuer un filtrage dans l'implémentation?
public interface IMyRepository
{
IQueryable<MyClass> GetAll();
}
Mis en œuvre en:
public class LINQtoSQLRepository : IMyRepository
{
public IQueryable<MyClass> GetAll()
{
return from table in dbContext.table
select new MyClass
{
Field1 = table.field1,
... etc.
}
}
}
Filtre pour ID:
public static class TableFilters
{
public static MyClass WithID(this IQueryable<MyClass> qry, string id)
{
return (from t in qry
where t.ID == id
select t).SingleOrDefault();
}
}
Appelée du service:
public class TableService
{
public MyClass RecordsByID(string id)
{
return _repository.GetAll()
.WithID(id);
}
}
je suis tombé sur un problème quand j'expérimenté avec la mise en œuvre du référentiel utilisant Entity Framew ork avec LINQ to Entities. La classe de filtres dans mon projet contient des opérations plus complexes que le "WHERE ... == ..." dans l'exemple ci-dessus, qui, selon moi, nécessite des implémentations différentes selon le fournisseur LINQ. Plus précisément, j'ai besoin d'exécuter une clause SQL "WHERE ... IN ...". Je suis en mesure de mettre en œuvre ce dans la classe de filtre à l'aide:
string[] aParams = // array of IDs
qry = qry.Where(t => aParams.Contains(t.ID));
Cependant, afin d'effectuer ce contre Entity Framework, je dois fournir une solution telle que la BuildContainsExpression qui est lié à l'Entity Framework. Cela signifie que je dois avoir 2 implémentations différentes de ce filtre particulier, en fonction du fournisseur sous-jacent.
J'apprécierais tout conseil sur la façon dont je devrais procéder à partir d'ici. Il m'a semblé que l'exposition d'un IQueryable à partir de mon dépôt me permettrait d'effectuer des filtres indépendamment du fournisseur sous-jacent, ce qui me permettrait de passer d'un fournisseur à l'autre si nécessaire. Cependant le problème que je décris ci-dessus me fait penser que je devrais effectuer tout mon filtrage dans les dépôts et renvoyer IEnumerable, IList ou des classes uniques.
Un grand merci, Matt
Faux lieu. 'BuildContainsExpression' est * entièrement * indépendant de l'EF (il ne dépend que de Linq et d'Expressions). C'est aussi totalement inutile dans EF 4, qui supporte directement 'IEnumerable.Contains'. –