具有 AutoMapper 抛出异常的通用工作单元和存储库模式 "another entity of the same type already has the same primary key value"

Generic UnitofWork & Repository pattern with AutoMapper throwing exception "another entity of the same type already has the same primary key value"

我将以下 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);

得到以下异常

Attaching an entity of type 'Component' failed because another entity of the same type already has the same primary key value

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

请告知如何更正用法。

那是因为你使用的是Find方法。此方法会将返回的实体附加到您的上下文,稍后使用 Automapper 您将创建一个断开连接的 POCO 实体,稍后您将尝试使用通用存储库的 Update 方法将其附加到您的上下文,并且两个实体共享同样的Id。 使用 Any 扩展方法而不是 Find 来检查您的 table 中是否存在具有 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.");
 }