4

我想使用实体框架来持久化域实体。我的项目设置如下:-

  • UI:MVC(使用 Automapper 在域实体和视图模型之间进行映射)
  • 领域:实体、服务、存储库接口
  • 存储库:实体框架(实现领域层的接口)。使用 Automapper 在域实体和实体框架对象之间进行映射。

这很好用,除非在我的服务中,如果我通过检查存储库来验证项目,然后执行更新。这失败了,因为 Entity Frameworks 身份映射之前已经看到过该项目,我尝试再次附加它。

我可以使用如下代码解决这个问题(这将变得更通用)

        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();
    }

我确信一定有更好的方法来实现我想要做的事情,但我无法为我的生活弄清楚什么!

对于上述方法的任何其他一般性评论将不胜感激,因为我即将在大型项目中使用它!

谢谢

罗斯

4

2 回答 2

1

正如 trailmax 所说,看起来你有多个数据上下文。我会为一个数据上下文拍摄。这可以通过创建通用存储库来完成。假设您在实体和存储库之间有 1:1 的关系,这篇文章可能会帮助您实现目标:http ://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing -the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

于 2012-08-24T18:20:24.410 回答
0

除非我完全误读了您的问题,否则我认为您的问题是 DatabaseContext 对象的多个实例。如果你从一个上下文实例中获取一个对象,然后尝试在不同的上下文实例中使用它,你会得到很多异常:第二个上下文实例会看到该对象已经附加,但它不能使用它,因为它附加到不同的上下文实例。

如果您只有一个上下文实例来管理您的附加对象,它会看到该对象已经附加并且将使用它。而且您不需要使用 AutoMapper 将对象克隆(顺便说一下,成员级克隆的好技术!)到新实例和任何其他可怕的“TryingToAttachObject”东西中。

在我发现依赖注入之前,我在多个上下文实例中遇到了很多类似的问题,它很神奇:它会创建一个 DBContext 实例并将其用于您的所有请求和 EF 管理。

于 2012-08-24T11:25:30.217 回答