ASP.Net MVC 3 - unitOfWork.Commit() not saving anything
I created a web application using ASP.Net MVC 3 and EF 4.1, and I am using the UnitOfWork pattern, but nothing is getting committed to the database. All this is quite new to me, and I don't know where to start to resolve this issue.
I based myself on this post to create my web application:
http://weblogs.asp.net/shijuvarghese/archive开发者_StackOverflow社区/2011/01/06/developing-web-apps-using-asp-net-mvc-3-razor-and-ef-code-first-part-1.aspx
The final code, which can be obtained here also has a service layer and the UnitOfWOrk is being injected into the services.
Instead of using the custom injector based on Unity 2 as they are in that project, I am using Unity.Mvc3.
Here is my IUnitOfWork class:
public interface IUnitOfWork
{
void Commit();
}
And here is my UnitOfWork class:
public class UnitOfWork : IUnitOfWork
{
private readonly IDatabaseFactory databaseFactory;
private MyProjectContext dataContext;
public UnitOfWork(IDatabaseFactory databaseFactory)
{
this.databaseFactory = databaseFactory;
}
protected MyProjectContext DataContext
{
get { return dataContext ?? (dataContext = databaseFactory.Get()); }
}
public void Commit()
{
DataContext.Commit();
}
}
And here is how one of my service class look like:
public class RegionService : IRegionService
{
private readonly IRegionRepository regionRepository;
private readonly IUnitOfWork unitOfWork;
public RegionService(IRegionRepository regionRepository, IUnitOfWork unitOfWork)
{
this.regionRepository = regionRepository;
this.unitOfWork = unitOfWork;
}
...
}
At start-up, my UnitOfWork component is being registered like this:
container.RegisterType<IUnitOfWork, UnitOfWork>();
Now, no matter whether I try to insert, update or delete, no request is being sent to the database. What am my missing here?
UPDATE:
Here is the content of DataContext.Commit():
public class MyProjectContext : DbContext
{
public DbSet<Region> Regions { get; set; }
public virtual void Commit()
{
base.SaveChanges();
}
}
And here is databaseFactory.Get():
public interface IDatabaseFactory : IDisposable
{
MyProjectContext Get();
}
UPDATE #2:
Using the debugger, I am noticing that my Region service and controller constructors are getting called once when performing only a select, but they are called twice when performing an update. Is this normal?
Ok, I found the culprit. It has to do with how I was registering my database factory.
Instead of
container.RegisterType<IDatabaseFactory, DatabaseFactory>();
I needed
container.RegisterType<IDatabaseFactory, DatabaseFactory>(new HierarchicalLifetimeManager());
I found the information on this web site:
http://www.devtrends.co.uk/blog/introducing-the-unity.mvc3-nuget-package-to-reconcile-mvc3-unity-and-idisposable
That's an awfully complex implementation of Unit of Work. I actually prefer this one:
http://azurecoding.net/blogs/brownie/archive/2010/09/22/irepository-lt-t-gt-and-iunitofwork.aspx
Much simpler, and much more flexible. Although you do have to work out a few things for yourself.
May just be a typo but in UnitOfWork your private MyProjectContext is called dataContext (lowercase d)
But in your commit method your calling DataContext.Commit. Any chance that's actually calling a static method that you didn't intend to call? More likely a typo but thought I'd point it out.
+1 for an overly complex implementation of UnitOfWork.
精彩评论