Ich versuche, das beste Muster für den Datenzugriff in meiner MVC-Anwendung zu entscheiden. Derzeit habe ich die MVC-Storefront-Serie verfolgt und verwende Repositories, die IQueryable einer Service-Schicht aussetzen, die dann Filter anwendet. Anfangs verwende ich LINQtoSQL, z.Sollten Repositorys IQQueryable der Service-Schicht aussetzen oder in der Implementierung filtern?
public interface IMyRepository
{
IQueryable<MyClass> GetAll();
}
in Implementiert:
public class LINQtoSQLRepository : IMyRepository
{
public IQueryable<MyClass> GetAll()
{
return from table in dbContext.table
select new MyClass
{
Field1 = table.field1,
... etc.
}
}
}
Filter für IDs:
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();
}
}
aus dem Dienst aufgerufen:
public class TableService
{
public MyClass RecordsByID(string id)
{
return _repository.GetAll()
.WithID(id);
}
}
ich in ein Problem lief, als ich mit der Umsetzung der experimentierten Repository mit Entity Framew Ork mit LINQ zu Entitäten. Die Filterklasse in meinem Projekt enthält einige komplexere Operationen als das "WHERE ... == ..." im obigen Beispiel, von dem ich glaube, dass je nach LINQ-Provider unterschiedliche Implementierungen erforderlich sind. Insbesondere muss ich eine SQL-Klausel "WHERE ... IN ..." ausführen. Ich bin in der Lage dies in der Filterklasse zu implementieren mit:
string[] aParams = // array of IDs
qry = qry.Where(t => aParams.Contains(t.ID));
Um jedoch das gegen Entity Framework auszuführen, ich brauche eine Lösung wie die BuildContainsExpression zu schaffen, die auf die Entity Framework gebunden ist. Dies bedeutet, dass ich zwei verschiedene Implementierungen dieses speziellen Filters haben muss, abhängig vom zugrunde liegenden Provider.
Ich würde mich über jeden Hinweis freuen, wie ich von hier fortfahren sollte. Es schien mir, dass die Bereitstellung eines IQueryable aus meinem Repository es mir ermöglichen würde, Filter unabhängig vom zugrundeliegenden Provider durchzuführen, so dass ich bei Bedarf zwischen den Providern wechseln konnte. Das Problem, das ich oben beschrieben habe, lässt mich jedoch denken, dass ich meine gesamte Filterung innerhalb der Repositories durchführen und IEnumerable, IList oder einzelne Klassen zurückgeben sollte.
Vielen Dank, Matt
Falsche Prämisse. 'BuildContainsExpression' ist * völlig * unabhängig von der EF (hängt nur von Linq und Expressions ab). Es ist auch völlig unnötig in EF 4, das 'IEnumerable.Contains' direkt unterstützt. –