Problem updating through LINQtoSQL in MVC application using StructureMap, Repository Pattern and UoW
- by matt
I have an ASP MVC application using LINQ to SQL for data access.
I am trying to use the Repository and Unit of Work patterns, with a service layer consuming the repositories and unit of work.
I am experiencing a problem when attempting to perform updates on a particular repository.
My application architecture is as follows:
My service class:
public class MyService
{
private IRepositoryA _RepositoryA;
private IRepositoryB _RepositoryB;
private IUnitOfWork _unitOfWork;
public MyService(IRepositoryA ARepositoryA, IRepositoryB ARepositoryB, IUnitOfWork AUnitOfWork)
{
_unitOfWork = AUnitOfWork;
_RepositoryA = ARepositoryA;
_RepositoryB = ARepositoryB;
}
public PerformActionOnObject(Guid AID)
{
MyObject obj = _RepositoryA.GetRecords()
.WithID(AID);
obj.SomeProperty = "Changed to new value";
_RepositoryA.UpdateRecord(obj);
_unitOfWork.Save();
}
}
Repository interface:
public interface IRepositoryA
{
IQueryable<MyObject> GetRecords();
UpdateRecord(MyObject obj);
}
Repository LINQtoSQL implementation:
public class LINQtoSQLRepositoryA : IRepositoryA
{
private MyDataContext _DBContext;
public LINQtoSQLRepositoryA(IUnitOfWork AUnitOfWork)
{
_DBConext = AUnitOfWork as MyDataContext;
}
public IQueryable<MyObject> GetRecords()
{
return from records in _DBContext.MyTable
select new MyObject
{
ID = records.ID,
SomeProperty = records.SomeProperty
}
}
public bool UpdateRecord(MyObject AObj)
{
MyTableRecord record = (from u in _DB.MyTable
where u.ID == AObj.ID
select u).SingleOrDefault();
if (record == null)
{
return false;
}
record.SomeProperty = AObj.SomePropery;
return true;
}
}
Unit of work interface:
public interface IUnitOfWork
{
void Save();
}
Unit of work implemented in data context extension.
public partial class MyDataContext : DataContext, IUnitOfWork
{
public void Save()
{
SubmitChanges();
}
}
StructureMap registry:
public class DataServiceRegistry : Registry
{
public DataServiceRegistry()
{
// Unit of work
For<IUnitOfWork>()
.HttpContextScoped()
.TheDefault.Is.ConstructedBy(() => new MyDataContext());
// RepositoryA
For<IRepositoryA>()
.Singleton()
.Use<LINQtoSQLRepositoryA>();
// RepositoryB
For<IRepositoryB>()
.Singleton()
.Use<LINQtoSQLRepositoryB>();
}
}
My problem is that when I call PerformActionOnObject on my service object, the update never fires any SQL. I think this is because the datacontext in the UnitofWork object is different to the one in RepositoryA where the data is changed. So when the service calls Save() on it's IUnitOfWork, the underlying datacontext does not have any updated data so no update SQL is fired.
Is there something I've done wrong in the StrutureMap registry setup? Or is there a more fundamental problem with the design?
Many thanks.