I've been developing an ASP.NET MVC4
project from scratch by myself using separate project for my data access layer. There I am using Entity Framework 5
with Code First
workflow and I've implemented I think a very standard Repository pattern
plus Uint Of Work
to separate the data layer from the business logic.
Everything was working as expected and I have already a lot of business logic, but I don't have too much experience (about 9 months total) and now a very experienced developer is joining to the project and suddenly I started to get this error:
The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
The structure of my project is this -
Just a part from my UnitOfWork
class :
public class UnitOfWork : IDisposable
{
private MyDbContext context = new MyDbContext ();
private MenuRepository мenuRepository;
public MenuRepository MenuRepository
{
get
{
if (this.мenuRepository == null)
this.мenuRepository = new MenuRepository(context);
return мenuRepository;
}
}
//register other repositories...
}
And the my repositories have a standard look:
public class MenuRepository : GenericRepository<Menu>, IMenuRepository
{
public MenuRepository(MyDbContext context) : base(context) { }
}
I know that this is not enough to tell if the implementation is good enough or not but it was working for a few months without noticing any problems. Today I was implementing a logic for editing a menu with submenus :
Menu menu = unitOfWork.MenuRepository.GetById(model.MenuID);
long menuItemId = menu.MenuItems[0].MenuItemID;
if (menu != null)
{
menu.Name = model.MenuName;
MenuItem menuItem = unitOfWork.MenuItemRepository.GetById(menuItemId);
menuItem.Name = "Test";
unitOfWork.MenuRepository.Update(menu);
return View(model);
}
This is all happening in my controller where I have this :
private UnitOfWork unitOfWork = new UnitOfWork();
So when I tried to execute this code I got the error from above for the ..attached to different ObjectContext objects.
.
The only change that I've noticed from before the code started to crash was this added from the other guy directly into the Menu
entity :
//private DAL.UnitOfWork.UnitOfWork unitOfWork = new DAL.UnitOfWork.UnitOfWork();
public Menu()
{
MenuItems = new List<MenuItem>();
}
public int MenuID { get; set; }
//private int menuId;
//public int MenuID {
// get
// {
// return menuId;
// }
// set
// {
// menuId = value;
// if (MenuItems.Count == 0)
// {
// MenuItems = unitOfWork.MenuItemRepository.GetBy(x => x.MenuID == menuId).ToList();
// }
// }
//}
After I commented all the stuff above and returned it to public int MenuID { get; set; }
without the additional logic, dropping the database and recreating it I was able to continue to use my Update
logic from the controller without the error for the different object contexts.
So my question is - is using UnitOfWork
directly from the entity acceptable at all. I've implemented the Data Access Layer
but I've used a lot of information from different articles and I can't say that I fully understand the reason behind everything. However it seems to me that using it this way not only causes the code to crash but also is against the whole idea for using Repositories
and UnitOfWork
to manage your data. On the other hand the guy that has added this code has more than 10 years of programming experience so I can't just tell him he must change his code. So is it in fact OK to use unitOfWork
from inside the entity itself as in the example above and if it's actually is, then how can I resolve the error with the different object contexts being used?