views:

3849

answers:

2

With the introduction of .NET 3.5 and the IQueryable<T> interface, new patterns will emerge. While I have seen a number of implementations of the Specification pattern, I have not seen many other patterns using this technology. Rob Conery's Storefront application is another concrete example using IQueryable<T> which may lead to some new patterns.

What patterns have emerged from the useful IQueryable<T> interface?

+6  A: 

It has certainly made the repository pattern much simpler to implement as well. You can essentially create a generic repository:

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

and then use it with linq:

var query = from customers in _repository.Find<Customer>() 
            select customers;
Fredrik Kalseth
+5  A: 

I like the repository-filter pattern. It allows you to separate concerns from the middle and data end tier without sacrificing performance.

Your data layer can concentrate on simple list-get-save style operations, while your middle tier can utilize extensions to IQueryable to provide more robust functionality:

Repository (Data layer):

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

Filter (Service layer):

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

This is a simple example, but filters can be safely combined to build more complicated queries. The performance is saved because the list isn't materialized until all the filters have been built into the query.

I love it because I dislike application-specific repositories!

BC