通用工作单元&使用AutoMapper抛出异常的存储库模式"同一类型的另一个实体已经具有相同的主键值"

时间:2016-03-08 18:34:30

标签: c# entity-framework automapper repository-pattern unit-of-work

我使用以下GitHub项目来获取通用存储库和UoW模式

https://genericunitofworkandrepositories.codeplex.com/

    [HttpPost]
    [Route("update")]
    public HttpResponseMessage Update(HttpRequestMessage request, ComponentViewModel component)
    {
        return CreateHttpResponse(request, () =>
        {
            HttpResponseMessage response = null;

            if (!ModelState.IsValid)
            {
                response = request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }
            else
            {
                var componentDb = UnitOfWork.Repository<Component>().Find(component.ID);

                if (componentDb == null)
                    response = request.CreateErrorResponse(HttpStatusCode.NotFound, "Invalid component.");
                else
                {
                    componentDb = Mapper.Map<ComponentViewModel, Component>(component);
                    UnitOfWork.Repository<Component>().Update(componentDb); // <-- ERROR'S HERE

                    UnitOfWork.SaveChanges();
                    response = request.CreateResponse<ComponentViewModel>(HttpStatusCode.OK, component);
                }
            }

            return response;
        });
    }

我在UnitOfWork.Repository<Component>().Update(componentDb);

处收到以下异常
  

附加类型&#39;组件&#39;的实体因为另一个实体而失败   相同类型的已经具有相同的主键值

我认为这是由于之前的AutoMapper Mapper.Map代码,但是,我不确定如何纠正它。

请告知如何纠正使用方法。

1 个答案:

答案 0 :(得分:3)

这是因为您使用的是Find方法。此方法将返回的实体附加到您的上下文,稍后使用Automapper创建一个断开连接的POCO实体,稍后您尝试使用通用存储库的Update方法将其附加到上下文,并且两个实体共享相同的Id。 使用Any扩展方法代替Find来检查表格中是否存在Id的实体:

 if (UnitOfWork.Repository<Component>().Any(c=>c.Id==component.ID))// Call Any here
 {
       componentDb = Mapper.Map<ComponentViewModel, Component>(component);
       UnitOfWork.Repository<Component>().Update(componentDb); 
       UnitOfWork.SaveChanges();
       response = request.CreateResponse<ComponentViewModel>(HttpStatusCode.OK, component);
 }
 else
 {
      response = request.CreateErrorResponse(HttpStatusCode.NotFound, "Invalid component.");
 }