I have found that there are often times that I use the same queries against an object set but I end up writing the same or very similar LINQ statements against my context. This however can be solved by use a object specific repository. Below is the implementation over Entity Framework 4.1 and the AdventureWorks sample.
We start with a plain console application and add a EntityContext folder.

Then we add new item ADO.NET Entity Data Model – Name it AdventureWorks.edmx. Use the wizard to connect to the local database for AdventureWorks. Then we add another Folder for our Repository Implementations. This is going to follow the patterns discussed in the Repository patterns post and POCO separation posts.
using System;
using System.Data.Objects;
using System.Linq;
using ObjectRepository.EntityContext;
namespace ObjectRepository.Repository
{
public class EntityFrameworkRepository : IRepository
{
private readonly ObjectContext _context;
public EntityFrameworkRepository(ObjectContext context)
{
_context = context;
}
public IQueryable<T> AsQueryable<T>() where T : class
{
return _context.CreateObjectSet<T>();
}
public void SaveChanges()
{
_context.SaveChanges();
}
public void Delete<T>(T item) where T : class
{
_context.DeleteObject(item);
}
public void Add<T>(T item) where T : class
{
_context.CreateObjectSet<T>().AddObject(item);
}
public void Attach<T>(T item) where T : class
{
_context.CreateObjectSet<T>().Attach(item);
}
public void Detach<T>(T item) where T : class
{
_context.Detach(item);
}
}
}
This gives us the base to use, and we could use it as is.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ObjectRepository.EntityContext;
using ObjectRepository.Repository;
namespace ObjectRepository
{
class Program
{
static void Main(string[] args)
{
IRepository repository = new EntityFrameworkRepository(new AdventureWorksEntities());
var longRunningProducts = repository.AsQueryable<Product>().Where(x => x.DaysToManufacture > 3);
}
}
}
If we have to use the same long running products query a few times it is going to get old typing it and we have no control over the magic “3”. So how about we wrap a Product specific Repository.
using System.Linq;
using ObjectRepository.EntityContext;
namespace ObjectRepository.Repository
{
public class ProductRepository : IProductRepository
{
private readonly IRepository _repository;
public ProductRepository(IRepository repository)
{
_repository = repository;
}
public IQueryable<Product> GetLongRunningProducts()
{
return _repository.AsQueryable<Product>().Where(x => x.DaysToManufacture > 3);
}
}
}
namespace ObjectRepository.Repository
{
public interface IProductRepository
{
IQueryable<Product> GetLongRunningProducts();
}
}
Then our usage becomes this…
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ObjectRepository.EntityContext;
using ObjectRepository.Repository;
namespace ObjectRepository
{
class Program
{
static void Main(string[] args)
{
IRepository repository = new EntityFrameworkRepository(new AdventureWorksEntities());
IProductRepository productRepository = new ProductRepository(repository);
var longRunningProducts = productRepository.GetLongRunningProducts();
}
}
}
Now no matter where you use the long running products you have the same result, no one has to remember the magic “3” and if it changes it only changes once. This will also allow you to wrap the queries in unit test and integration tests for performance but that is another post.
Source Code is here
62caa3bf-0791-45f3-a492-2d6b15938d5d|1|5.0
Data Access, Design Patterns, Entity Framework