Over the past week or so we've been keeping an eye on Rob Conery's blog, watching his series of "MVC Storefront" screencasts. Rob's putting together an e-commerce site using the new ASP.NET MCV framework, and he's doing it from the ground up as an exercise in test-driven development (TDD).

Rob's approach involves a "repository" layer, which is essentially a class that's very close to the underlying data store. If I'm right, it'll eventually give him basic CRUD operations that he can call from the next layer up, his "service" layer. Right now it has a "GetProducts" method which returns an IQueryable<Product> - so he has a way to get a query that can give him a list of all products. To that he has added some extension methods so that he can dynamically add "where" clauses to that query. He ended up with code like this:

var prods = _repository.GetProducts().WithCategory(1).ToList();

This is a really interesting approach, in that he's able to "pipeline" his "where" clauses to chain together a query, which he then "executes" by calling ToList() at the end.

Here's where I'm not following him though:

Right now, all of Rob's tests are hitting a faked-out version of his repository. He's got his GetProducts fake method just returning a dummy list of products which he's instantiating on the fly. His goal, as I see it, is to eventually plug in a LINQ to SQL implementation so the queries are passed directly to the database. However, LINQ to SQL is going to want to define its own entity classes for Product, Category etc. I know that LINQ to SQL has some sort of rudimentary mapping technology so you can map your custom classes to it, but is that the direction it's going to go? What if his Product class had an actual Category property of type Category, rather than a CategoryID property of type int? Surely then it would be much harder to map that directly to a LINQ to SQL entity?

In a small project we've just started here at work, we're trying to emulate Rob's approach - TDD, repository and service layers etc. However, I don't think I want to go down this "chaining queries" path using IQueryable<T> just yet - I'm just not convinced that it'll work when we come to implement the repository as a LINQ to SQL class. Instead we're going to give the repository methods that wrap entire queries (eg "GetProductsByCategoryID").

I'm really looking forward to part four of Rob's screencast, though - it's has been very enlightening.