2008-09-22 7 views
14

Avec l'introduction de .NET 3.5 et l'interface IQueryable<T>, de nouveaux modèles apparaîtront. Bien que j'ai vu un certain nombre de mises en œuvre du modèle de spécification, je n'ai pas vu beaucoup d'autres modèles utilisant cette technologie. L'application Storefront de Rob Conery est un autre exemple concret utilisant IQueryable<T> qui peut conduire à de nouveaux modèles.Création de modèles utilisant IQueryable <T>

Quels modèles ont émergé de l'interface utile IQueryable<T>?

Répondre

8

Il a certainement rendu le modèle de référentiel beaucoup plus simple à implémenter. Vous pouvez essentiellement créer un référentiel générique:

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.. **/ 
} 

puis l'utiliser avec LINQ:

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

J'aime le modèle référentiel-filtre. Il vous permet de séparer les problèmes du niveau intermédiaire et de fin de données sans sacrifier les performances.

Votre couche de données peut se concentrer sur les opérations simples de style liste-get-save, alors que votre niveau intermédiaire peut utiliser des extensions à IQueryable pour fournir des fonctionnalités plus robustes:

dépôt (couche de données):

public class ThingRepository : IThingRepository 
{ 
    public IQueryable<Thing> GetThings() 
    { 
     return from m in context.Things 
       select m; // Really simple! 
    } 
} 

filtre (couche de service):

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); 
} 

Ceci est un exemple simple, mais les filtres peuvent être combinés en toute sécurité pour générer des requêtes plus complexes. Les performances sont enregistrées car la liste n'est matérialisée que lorsque tous les filtres ont été intégrés dans la requête. Je l'aime parce que je n'aime pas les dépôts spécifiques à l'application!

+0

Qu'en est-il des filtres de type croisé? Je veux dire, que faire si vous voulez quelque chose comme 'code' IQueryable choses2 = repo.GetThings(). ForUserId (userId) .GetSubthings()' code'? Souhaitez-vous faire GetSubthings() quelque chose comme ceci: 'code'GetSubThings (ce IQueryable choses, IQueryable sous-titres) {}' code'? – mayu

+0

Non, je voudrais créer une deuxième classe d'extension pour 'IQueryable ', appelez-la 'HavingStatus()' qui serait disponible pour des choses comme 'GetThings(). ForUserId (userId) .Subthings.HavingStatus (status)' ... Parce que si Thing est LinqToSql, il définit déjà 'Subthings' de sorte que vous n'avez pas besoin d'une classe d'extension' GetSubthings() ' –

Questions connexes