entity-framework – 将实体附加到上下文失败,因为它已经存在

我使用Code of Work的Unity和Work通用存储库.

为了更新实体,通用仓库具有:

    public virtual void Update(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State == EntityState.Detached)
        {
            DbSet.Attach(entity);
        }  
        dbEntityEntry.State = EntityState.Modified;
    }

web api方法:

    public HttpResponseMessage Put(MyEditModel editModel)
    {
        var model = editModel.MapToMyEntity();
        _myManager.Update(model);
        return new HttpResponseMessage(HttpStatusCode.NoContent);
    }

更新方法:

    public void Update(MyEntity model)
    {
        Uow.MyEntities.Update(model);
        Uow.Commit();
    }

在团结工作中:

IRepository<MyEntity> MyEntities { get; }

更新实体时,我收到以下错误:

Additional information: Attaching an entity of type ‘X’ failed because another entity of the same type already has the same primary key value.
This can happen when using the ‘Attach’ method or setting the state of an entity to ‘Unchanged’ or ‘Modified’ if any entities in the graph have conflicting key values.
This may be because some entities are new and have not yet received database-generated key values.
In this case use the ‘Add’ method or the ‘Added’ entity state to track the graph and then set the state of non-new entities to ‘Unchanged’ or ‘Modified’ as appropriate.

>当它是您调用存储库的第一个方法时,更新工作正常.
(我创建了一个ID已存在于DB中的实体并调用了Update.)
>在更新实体之前获取实体时,更新不起作用.
(例如,我得到一个实体X,将其转换为DTO,然后在UI中更改一些值,
然后调用一个web api,用新的值创建一个实体X.
调用存储库的更新.)

有什么想法可以避免这个吗
当你有一个CRUD应用程序时,你总是在更新之前调用get.

最佳答案 我正在使用自己的附加方法:

public void Attach<E>(ref E entity)
{
    if (entity == null)
    {
        return;
    }

    try
    {
        ObjectStateEntry entry;
        bool attach = false;
        if (ObjectStateManager.TryGetObjectStateEntry(CreateEntityKey(entitySetName, entity), out entry))
        {
            attach = entry.State == EntityState.Detached;

            E existingEntityInCache = (E)entry.Entity;
            if (!existingEntityInCache.Equals(entity))
            {
                existingEntityInCache.SetAllPropertiesFromEntity(entity);
            }
            entity = existingEntityInCache;
        }
        else
        {
            attach = true;
        }
        if (attach)
            objectContext.AttachTo(entitySetName, entity);
    }
    catch (Exception ex)
    {
        throw new Exception("...");
    }
}
点赞