【发布时间】:2014-01-12 01:01:31
【问题描述】:
我一直在自己从头开始开发一个ASP.NET MVC4 项目,并为我的数据访问层使用单独的项目。我正在使用Entity Framework 5 和Code First 工作流,并且我已经实现了我认为非常标准的Repository pattern 加上Uint Of Work 将数据层与业务逻辑分开。
一切都按预期进行,我已经有很多业务逻辑,但我没有太多经验(总共大约 9 个月),现在一位非常有经验的开发人员正在加入该项目,突然我开始了解这个错误:
无法定义两个对象之间的关系,因为 它们附加到不同的 ObjectContext 对象。
我的项目结构是这样的-
只是我的UnitOfWork 课程的一部分:
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...
}
我的存储库具有标准外观:
public class MenuRepository : GenericRepository<Menu>, IMenuRepository
{
public MenuRepository(MyDbContext context) : base(context) { }
}
我知道这不足以判断实施是否足够好,但它运行了几个月而没有发现任何问题。今天我正在实现一个用子菜单编辑菜单的逻辑:
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);
}
这一切都发生在我的控制器中:
private UnitOfWork unitOfWork = new UnitOfWork();
因此,当我尝试执行此代码时,我从上面得到了 ..attached to different ObjectContext objects. 的错误。
在代码开始崩溃之前我注意到的唯一变化是从其他人直接添加到 Menu 实体中:
//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();
// }
// }
//}
在我评论了上面的所有内容并将其返回给public int MenuID { get; set; } 之后,没有附加逻辑,删除数据库并重新创建它,我能够继续从控制器中使用我的Update 逻辑,而不会出现其他对象的错误上下文。
所以我的问题是 - 直接从完全可以接受的实体中使用UnitOfWork。我已经实现了Data Access Layer,但我使用了来自不同文章的大量信息,我不能说我完全理解这一切背后的原因。但是在我看来,以这种方式使用它不仅会导致代码崩溃,而且与使用 Repositories 和 UnitOfWork 管理数据的整个想法背道而驰。另一方面,添加此代码的人有超过 10 年的编程经验,所以我不能只告诉他必须更改他的代码。那么实际上是否可以像上面的示例一样从实体本身内部使用unitOfWork,如果确实如此,那么我该如何解决使用不同对象上下文的错误?
【问题讨论】:
-
在我看来,域对象使用工作单元是不行的。域模型应该是持久性无知的。该帖子包含有关为什么stackoverflow.com/questions/905498/… 的信息。加上 msdn 的那篇文章,好好恢复吧msdn.microsoft.com/en-us/magazine/dd882510.aspx
标签: c# design-patterns ef-code-first entity-framework-5 unit-of-work