Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design Patterns using IQueryable<T>

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?

like image 755
Brad Leach Avatar asked Sep 22 '08 10:09

Brad Leach


2 Answers

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;
like image 87
Fredrik Kalseth Avatar answered Nov 18 '22 08:11

Fredrik Kalseth


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!

like image 25
BC. Avatar answered Nov 18 '22 07:11

BC.