2008-09-22 10 views
14

Mit der Einführung von .NET 3.5 und der IQueryable<T> Schnittstelle werden neue Muster entstehen. Während ich eine Anzahl von Implementierungen des Spezifikationsmusters gesehen habe, habe ich nicht viele andere Muster gesehen, die diese Technologie verwenden. Rob Conerys Storefront-Anwendung ist ein anderes konkretes Beispiel, das IQueryable<T> verwendet, das zu einigen neuen Mustern führen kann.Entwurfsmuster mit IQueryable <T>

Welche Muster sind aus der nützlichen Schnittstelle IQueryable<T> hervorgegangen?

Antwort

8

Es hat sicherlich dazu beigetragen, das Repository-Muster viel einfacher zu implementieren. Sie können im Wesentlichen eine generische Repository erstellen:

public class LinqToSqlRepository : IRepository 
{ 
    private readonly DataContext _context; 

    public LinqToSqlRepository(DataContext context) 
    { 
     _context = context; 
    } 

    public IQueryable<T> Find<T>() 
    { 
     return _dataContext.GetTable<T>(); // linq 2 sql 
    } 

    /** snip: Insert, Update etc.. **/ 
} 

und dann verwenden, mit Linq:

var query = from customers in _repository.Find<Customer>() 
      select customers; 
7

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!

+0

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

+0

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 –