实体框架和存储库模式

时间:2012-08-15 16:02:00

标签: entity-framework

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

  • UI:MVC(使用Automapper在域实体和视图模型之间进行映射)
  • 域:Entites,服务,存储库接口
  • 存储库:实体框架(从域层实现接口)。使用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();
    }

我确信必须有一种更好的方式来实现我想要做的事情,但我不能为我的生活弄清楚什么!

关于上述方法的任何其他一般性评论都会受到赞赏,因为我即将在大型项目中使用它!

由于

罗斯

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

如果您只有一个用于管理附加对象的上下文实例,则会看到该对象已经附加,并且只能使用它。而且你不需要使用AutoMapper克隆对象(顺便提一下克隆成员克隆的方法!)到新实例和任何其他可怕的“TryingToAttachObject”东西。

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