Specialised LINQ to SQL Repositories
09 Feb 2008 by Nigel SampsonWe finished off last time with creating a Repository<T> class and
matching interface. This is a general workhorse of a class that allows
such syntax as
IRepository<Item> repository = new Repository<Item>(new InMemoryUnitOfWork);
IEnumerable<Item> outOfStock = from i in repository where i.QuantityOnHand == 0 select i;
foreach(Item item in repository) { }
What I'd like however is to be able to encapsulate some of the more complex queries behind specialised repositories, these repositories can can then mocked with tools other than TypeMock and move some great interaction based testing. We'll start by moving the out of stock query above to an ItemRepository
public interface IItemRepository
{
IEnumerable<Item> GetOutOfStockItems();
}
public class ItemRepository : Repository<Item>, IItemRepository
{
public ItemRepository(IUnitOfWork unitOfWork)
: base(unitOfWork)
{
}
public IEnumerable<Item> GetOutOfStockItems()
{
return outOfStock = from i in this where i.QuantityOnHand == 0 select i;
}
}
The LINQ query does look a little odd since we're querying the repository directly, in order to make this a little more readable I add a property
IQueryable<Item> Items
{
get { return this; }
}
to make the LINQ query
from i in Items where i.QuantityOnHand == 0 select i;
Interestingly because IItemRepository doesn't implement IRepository<Item> we lose externally the ability to execute LINQ queries against it (this could be desired through). I prefer altering it however to
public interface IItemRepository : IRepository<Item>
in order the use of LINQ and normal repository actions throughout the system while only refactoring complex or commonly used queries into the repository itself.