Ich mag das Repository-Filtermuster. Sie können Probleme von der mittleren und der Datenendstufe trennen, ohne die Leistung zu beeinträchtigen.
Ihre Datenschicht auf das konzentrieren können einfache list-get-Stil speichern Operationen, während die mittlere Ebene Erweiterungen IQueryable nutzen können robustere Funktionalität zu bieten:
Repository (Data Layer):
public class ThingRepository : IThingRepository
{
public IQueryable<Thing> GetThings()
{
return from m in context.Things
select m; // Really simple!
}
}
Filter (Service-Schicht):
public static class ServiceExtensions
{
public static IQueryable<Thing> ForUserID(this IQueryable<Thing> qry, int userID)
{
return from a in qry
where a.UserID == userID
select a;
}
}
Service:
public GetThingsForUserID(int userID)
{
return repository.GetThings().ForUserID(userID);
}
Dies ist ein einfaches Beispiel, aber Filter können problemlos kombiniert werden, um komplexere Abfragen zu erstellen. Die Leistung wird gespeichert, da die Liste erst dann erstellt wird, wenn alle Filter in die Abfrage integriert wurden.
Ich liebe es, weil ich keine anwendungsspezifischen Repositories mag!
Was ist mit Kreuzfilter? Ich meine, was ist, wenn Sie etwas wie 'code' wollen? IQueryable sachen2 = repo.GetThings(). ForUserId (userId) .GetSubthings()' code'? Würdest du GetSubthings() so etwas machen: 'code'GetSubThings (dieses IQueryable dinge, IQueryable subthings) {}' code'? –
mayu
Nein, ich würde eine zweite Erweiterungsklasse für 'IQueryable' erstellen, rufen Sie 'HavingStatus()', die für Dinge wie 'GetThings(). ForUserId (userId) .Subthings.HavingStatus (Status) '... Da Thing LinqToSql ist, definiert es bereits 'Subthings', so dass Sie keine Erweiterungsklasse' GetSubthings() 'brauchen –