Linq is awesome, async / await is awesome, but combining them can be a little awkward. None of the standard linq operations are written to deal with async lambdas, this often leads to writing the async operations in a more procedural style approach rather than the functional one that Linq uses.
Here's a couple of useful extension methods I use, WhenAllAsync allows you to execute an aysnc method on a sequence of values. By using Task.WhenAll we can have the async method execute in parallel with each other.
The usage is pretty self explanatory, the only odd bit is that because DeleteAsync returns an IAsyncOperation rather than Task we use AsTask to convert it (or if you want right a second extension method using IAsyncOperation).
SelectAsync is useful for transforming a collection of values to another type via an asynchronous method. It's much like WhenAllAsync except that we return the result of the operation.
Most of the time I do any database interaction I follow a "Unit of Work" pattern. This allows good control over when work is submitted to the database, in terms of the Entity Framework, the Unit of Work controls the lifetime of the ObjectContext.
The implementation is pretty simple, we have a UnitOfWork static class that provides easy access to the current UOW as well as starting and disposing. We then have our IUnitOfWork which is where the work of accessing repositories and submitting changes to the database will be done. We then implement that with EntityUnitOfWork.
I like to follow the approach of "Unit of Work per Request" for web applications and usually handle this with an IHttpModule that manages it for me. However for MVC I wanted to try something different. One of the reasons I didn't like Module approach for MVC was that the UnitOfWork was still active during the rendering of the View. This meant that any complex lazy loaded queries could still be evaluated which could leave me vulnerable to N+1 problems.
In the end I created a UnitOfWorkAttribute which inherits from ActionFilterAttribute, this enables me to dispose of the current unit of work after the action is completed but before the view is processed. It means that if the view triggers anything that causes database access it throws an error. I can now enforce the convention that all data must be loaded by the action.
A long time ago I wrote a few posts about using "Domain Driven Design"-esque repositories using Linq to SQL ("Domain Driven Design Repositories in Linq to SQL"). I still use that general pattern with a few tweaks with extra layer of a "Unit of Work" to manage context lifetimes. I'm using this rebuild as a chance to play with Entity Framework 4 and so need to implement the appropriate interfaces all over again. The only major functionality change will be bringing in support for Entity Frameworks "Include".
I'm not going to go over the full pattern here, just the new parts for Entity Framework, the IRepository interface has changed that GetAll returns an interface IQuery which is pretty much the IQueryable interface with the Include method.
The implementations for IQuery and IRepository are as follows.
publicclassEntityRepository<T> : IRepository<T>where T : class
{
privatereadonlyObjectSet<T> objectSet;
public EntityRepository(ObjectSet<T> objectSet)
{
this.objectSet = objectSet;
}
publicIQuery<T> GetAll()
{
returnnewEntityQuery<T>(objectSet);
}
publicvoid Save(T entity)
{
if (entity ==null)
thrownewArgumentNullException("entity");
objectSet.AddObject(entity);
}
publicvoid Update(T entity)
{
if (entity ==null)
thrownewArgumentNullException("entity");
objectSet.Attach(entity);
}
publicvoid Delete(T entity)
{
if (entity ==null)
thrownewArgumentNullException("entity");
objectSet.DeleteObject(entity);
}
}
publicclassEntityQuery<T> : IQuery<T>
{
privatereadonlyObjectQuery<T> query;
public EntityQuery(ObjectQuery<T> query)
{
this.query = query;
}
publicIQuery<T> Include(string path)
{
returnnewEntityQuery<T>(query.Include(path));
}
IEnumerator<T>IEnumerable<T>.GetEnumerator()
{
return ((IEnumerable<T>)query).GetEnumerator();
}
IEnumeratorIEnumerable.GetEnumerator()
{
return ((IEnumerable)query).GetEnumerator();
}
ExpressionIQueryable.Expression
{
get
{
return ((IQueryable)query).Expression;
}
}
TypeIQueryable.ElementType
{
get
{
return ((IQueryable)query).ElementType;
}
}
IQueryProviderIQueryable.Provider
{
get
{
return ((IQueryable)query).Provider;
}
}
}
The actual Repository that gets used by the domain layer simply delegates all it's work back to a internal repository based off the current unit of work. This is important section because it decouples the domain repository from repository doing the actual work and allows me to change the underlying data source if necessary.
publicclassRepository<T> : IRepository<T>where T : class
{
privatestaticIRepository<T> Current
{
get
{
returnUnitOfWork.Current.CreateRepository<T>();
}
}
publicvirtualIQuery<T> GetAll()
{
return Current.GetAll();
}
publicvirtualvoid Save(T entity)
{
if (entity ==null)
thrownewArgumentNullException("entity");
Current.Save(entity);
}
publicvirtualvoid Update(T entity)
{
if (entity ==null)
thrownewArgumentNullException("entity");
Current.Update(entity);
}
publicvirtualvoid Delete(T entity)
{
if (entity ==null)
thrownewArgumentNullException("entity");
Current.Delete(entity);
}
}
I'll get into the Unit of Work stuff in my next post.
In 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).
publicclassRepository<T> : IRepository<T> where T : class
{
publicstaticIRepository<T> Current
{
get
{
returnUnitOfWork.Current.GetRepository<T>();
}
}
public Repository()
{
}
publicIQueryable<T> GetAll()
{
return Current;
}
publicvirtualvoid Update(T entity)
{
Current.Update(entity);
}
publicvirtualvoid Update(IEnumerable<T> entities)
{
Current.Update(entities);
}
publicvirtualvoid Delete(T entity)
{
Current.Delete(entity);
}
publicvirtualvoid Delete(IEnumerable<T> entities)
{
Current.Delete(entities);
}
publicvirtualvoid Save(T entity)
{
Current.Save(entity);
}
publicvirtualvoid Save(IEnumerable<T> entities)
{
Current.Save(entities);
}
publicIEnumerator<T> GetEnumerator()
{
return Current.GetEnumerator();
}
IEnumeratorIEnumerable.GetEnumerator()
{
return GetEnumerator();
}
TypeIQueryable.ElementType
{
get { return Current.ElementType; }
}
ExpressionIQueryable.Expression
{
get { return Current.Expression; }
}
IQueryProviderIQueryable.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.
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.
publicabstractclassActiveRecordBase<T> where T : ActiveRecordBase<T>, IIdentifiable
One important item in there is the IIdentifiable interface, I've seen
some posts around either using Dynamic Linq or reflection to implement
the GetById method but I prefer this. This won't work for all objects
that dont't have an identity column, but for most of mine it's fine.
This allows us something really cool, a kinda mix in. A conditional extension method on the repository class.
publicinterfaceIIdentifiable
{
int Id
{
get;
}
}
publicstatic T GetById<T>(thisIRepository<T> repository, int id) where T : class, IIdentifiable
So there's been a lot of commenting back and forth at the moment
concerning the new Microsoft Entity Framework and especially the "vote
of no confidence" by members of the Alt.Net and DDD communities. This I
can understand, the current EF certainly doesn't meet any of their
requirements for a toolset or framework.
The EF team looks to have taken some of this criticism on board and the Entity Framework Design blog gives some good indications we could end up with an excellent toolset.
The bastard step child in all of this is LINQ to SQL, certainly all the attention is on EF and as Ian Cooper
says "I would like to see a commitment from the Data Platform team to
stop
its focus on talking LINQ to SQL down as a RAD tool and tallking up its
advantages for use in the OO approaches to software development." I'd
like to see this as well. For small to medium projects this could an
excellent foundation, I'd love to see it opened up by the Data team,
the provider model for it is mostly there, hidden away under internals
and sealed classes.
On
a personal note, I'm still hunting for a product idea, my brain seems
to overly critical at the idea phase. I'm currently working on common
libraries for my work and I'll share some of the ideas that come out it
soon. I'd like to polish of the LINQ to SQL repositories and building
it into a business framework.