2008-09-22 16 views
14

Con la introducción de .NET 3.5 y la interfaz IQueryable<T>, surgirán nuevos patrones. Si bien he visto una serie de implementaciones del patrón de Especificación, no he visto muchos otros patrones que usan esta tecnología. La aplicación Robfront Store de Rob Conery es otro ejemplo concreto que usa IQueryable<T> que puede conducir a algunos patrones nuevos.Patrones de diseño usando IQueryable <T>

¿Qué patrones han surgido de la útil interfaz IQueryable<T>?

Respuesta

8

Ciertamente, ha simplificado mucho la implementación del patrón de repositorio. Puede crear un repositorio esencialmente genérica:

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

y luego usarlo con LINQ:

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

me gusta el patrón repositorio-filtro. Le permite separar las preocupaciones del nivel medio y final de datos sin sacrificar el rendimiento.

Su capa de datos se puede concentrar en una simple lista-conseguir-ahorrar operaciones de estilo, mientras que su nivel medio puede utilizar extensiones a IQueryable para proporcionar una funcionalidad más robusta:

Repositorio (capa de datos):

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

filtro (capa de Servicio):

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

Servicio:

public GetThingsForUserID(int userID) 
{ 
    return repository.GetThings().ForUserID(userID); 
} 

Este es un ejemplo simple, pero los filtros se pueden combinar de forma segura para crear consultas más complicadas. El rendimiento se guarda porque la lista no se materializa hasta que todos los filtros se hayan incorporado a la consulta.

¡Me encanta porque no me gustan los repositorios específicos de aplicaciones!

+0

¿Qué pasa con los filtros de tipo cruzado? Quiero decir, ¿y si quieres algo como 'código' IQueryable cosas2 = repo.GetThings(). ForUserId (userId) .GetSubthings()' code'? ¿Haría GetSubthings() algo como esto: 'code'GetSubThings (esto IQueryable cosas, IQueryable subthings) {}' code'? – mayu

+0

No, crearía una segunda clase de extensión para 'IQueryable ', llámala 'HavingStatus()' que estaría disponible para cosas como 'GetThings(). ForUserId (userId) .Subthings.HavingStatus (status)' ... . Porque si Thing es LinqToSql, ya define 'Subthings', por lo que no necesita una clase de extensión' GetSubthings() ' –