Implementing an ActiveRecord pattern in Linq to SQL
08 Sep 2008 by Nigel SampsonIn earlier posts I talked about about creating Domain Driven Design style repositories using Linq to SQL. These allowed us to swap between Linq to SQL repositories and In Memory ones easily (and really anything that could support IQueryable<T>, this ensured some very nice testabiliy. In this post I thought I'd go over some it again as well as a some refactoring I had done to simplfy things, as well as how to create simple Active Record style data access on top of our repositories and therefore still ensuring our testability.
Our IUnitOfWork and its implementations (SqlUnitOfWork and InMemoryUnitOfWork) haven't changed. However given that IDataSource<T> and IRepository<T> are essentially the same I decided to remove IDataSource<T>. Now that we have two implentations of IRepository<T> (InMemoryRepository and SqlRepository) we need one that uses these repositories and forms the base class for our aggregate repositories.
This base Repository<T> forms the foundation for it all, internally it's only really a decorator around the actual specialised repository that's accessed from the current Unit Of Work (more about this in a later post).
public class Repository<T> : IRepository<T> where T : class
{
public static IRepository<T> Current
{
get
{
return UnitOfWork.Current.GetRepository<T>();
}
}
public Repository()
{
}
public IQueryable<T> GetAll()
{
return Current;
}
public virtual void Update(T entity)
{
Current.Update(entity);
}
public virtual void Update(IEnumerable<T> entities)
{
Current.Update(entities);
}
public virtual void Delete(T entity)
{
Current.Delete(entity);
}
public virtual void Delete(IEnumerable<T> entities)
{
Current.Delete(entities);
}
public virtual void Save(T entity)
{
Current.Save(entity);
}
public virtual void Save(IEnumerable<T> entities)
{
Current.Save(entities);
}
public IEnumerator<T> GetEnumerator()
{
return Current.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
Type IQueryable.ElementType
{
get { return Current.ElementType; }
}
Expression IQueryable.Expression
{
get { return Current.Expression; }
}
IQueryProvider IQueryable.Provider
{
get { return Current.Provider; }
}
}
Active Record, this seems to be the way a lot of people think data access should be, a few static methods on your classes and away you go. From a testability point of view I feel repositories certainly work better, but for smaller data driven applications Active Record can certainly be the way to go. </p>
I'd
like to support both camps with this system so lets build on top of
what we already have, first we'll need a static accessor to the current
repository, we can do that through the unit of work, but since we
already that in our base class we'll just expose that. Now anytime we
need our repository it can be accessed through
Repositor<T>.Current. This lets us built our ActiveRecordBase.
``` csharp
public abstract class ActiveRecordBase