我希望使用实体框架来持久化领域实体。我的项目设置如下:
- UI: MVC(使用Automapper在领域实体和视图模型之间进行映射) - Domain: 实体、服务、存储库接口 - Repository: 实体框架(实现来自领域层的接口)。使用Automapper在领域实体和实体框架对象之间进行映射。
这很好用,除非在我的服务中,如果我执行像检查存储库一样验证项,然后执行更新操作,这将失败,因为实体框架的标识映射已经看到了该项,然后我尝试再次附加它。
我可以使用以下代码解决此问题(这将变得更加通用)。
问题是我发现自己不得不写相同类型的代码来进行删除。
我确信一定有更好的方法来实现我想要做的事情,但我却无论如何也想不出来!希望能得到关于上述方法的其他一般性评论,因为我将在一个大型项目中使用它!谢谢,Ross。
- UI: MVC(使用Automapper在领域实体和视图模型之间进行映射) - Domain: 实体、服务、存储库接口 - Repository: 实体框架(实现来自领域层的接口)。使用Automapper在领域实体和实体框架对象之间进行映射。
这很好用,除非在我的服务中,如果我执行像检查存储库一样验证项,然后执行更新操作,这将失败,因为实体框架的标识映射已经看到了该项,然后我尝试再次附加它。
我可以使用以下代码解决此问题(这将变得更加通用)。
public void Update(Domain.Entities.Book entity)
{
Book newBook = _mapper.Map<Domain.Entities.Book, Book>(entity);
ObjectStateEntry cacheEntry;
if (_dataContext.ObjectStateManager.TryGetObjectStateEntry(_dataContext.CreateEntityKey("Books",newBook), out cacheEntry))
{
_dataContext.Books.ApplyCurrentValues(newBook);
}
else
{
_dataContext.Books.Attach(newBook);
_dataContext.ObjectStateManager.ChangeObjectState(newBook, EntityState.Modified);
}
_dataContext.SaveChanges();
}
问题是我发现自己不得不写相同类型的代码来进行删除。
public void Delete(Domain.Entities.Book entity)
{
Book newBook = _mapper.Map<Domain.Entities.Book, Book>(entity);
ObjectStateEntry cacheEntry;
if (_dataContext.ObjectStateManager.TryGetObjectStateEntry(_dataContext.CreateEntityKey("Books", newBook), out cacheEntry))
{
_dataContext.ObjectStateManager.ChangeObjectState(cacheEntry.Entity, EntityState.Deleted);
}
else
{
_dataContext.Books.Attach(newBook);
_dataContext.ObjectStateManager.ChangeObjectState(newBook, EntityState.Deleted);
}
_dataContext.SaveChanges();
}
我确信一定有更好的方法来实现我想要做的事情,但我却无论如何也想不出来!希望能得到关于上述方法的其他一般性评论,因为我将在一个大型项目中使用它!谢谢,Ross。
TryGetObjectStateEntry
这样的高级方法,在我看来是代码异味。请注意,你的更新依赖于cacheEntry.Entity
代表了数据库中的原始状态的假设,否则ApplyCurrentValues
和更改跟踪将无法标记正确的属性为修改,以执行正确的DB UPDATE。你知道即使你不知道实体是否已经被连接也总是会发生吗? - SlaumaEntityObject
类派生的,那么你是正确的,它们不是POCO,并且直接依赖于EF。但是你可以使用POCO与EF,即不从任何EF特定内容派生的实体类(只需谷歌“Entity Framework POCO”或类似内容)。EF团队不鼓励使用EntityObject
,并建议使用POCO。你知道DbContext
和你正在使用的ObjectContext
相比吗?我建议你熟悉一下它,因为它简化了EF在许多方面的使用。 - Slauma