EntityFramework 更新实体失败 - 无法跟踪
EntityFramework fail on update entity - cannot be tracked
我的应用程序遇到了这个已知问题。
我尝试过使用 HasKey 和 HasAlternateKey 进行很多更改,甚至是 HasIndex、Unique 和 OnModelCreateCreating() 方法的其他变体。
我什至重新映射了我的实体,但仍然没有成功!
The instance of entity type 'Imoveis' cannot be tracked because
another instance with the key value '{Cod: 91}' is already being
tracked. When attaching existing entities, ensure that only one entity
instance with a given key value is attached.
我的 BaseRepository 的我的 Update() 方法 class:
public T Update(T entity)
{
DbContext.Entry(entity).State = EntityState.Modified; <-- Exception happens here
DbContext.SaveChanges();
return entity;
}
如何调用 Update()。这个问题发生在两个电话上。第二次尝试是防止此错误的失败方法:
public Imoveis InsertOrUpdateUniqueName(Imoveis imoveis)
{
try
{
if (imoveis.Cod > 0)
Update(imoveis);
else
Insert(imoveis);
return imoveis;
}
catch (Exception ex)
{
if (imoveis.Cod > 0)
{
if (ex is DbUpdateException)
{
if ((ex.InnerException as SqlException)?.Number == 2627)
return UpdateImovelDuplicado(imoveis);
}
else if (ex is InvalidOperationException)
{
var local = DbContext
.Set<Imoveis>()
.Local
.FirstOrDefault(x => x.Cod.Equals(imoveis.Cod));
if (local != null)
DbContext.Entry(local).State = EntityState.Detached;
return Update(imoveis);
}
}
throw ex;
}
}
已解决!
解决方案:
1 - 在我的案例(控制台应用程序)中,我删除了异步插入或更新,因为我使用了单例 DbContext。但这不是强制性的,视情况而定。您需要了解 DbContext 的生命周期。
2 - 我更改了 Update() 方法以从 DbContext Set 集合中恢复和分离原始对象。
这是我的新 Update() 方法,为通用对象调用新的 DetachLocal() 方法。
public T Update(T entity)
{
DetachLocal(entity);
DbContext.SaveChanges();
return entity;
}
public void DetachLocal(T t)
{
var keyname = GetIdName(t);
var keyValue = GetIdValue(t);
var local = DbContext.Set<T>()
.Local
.FirstOrDefault(entry => GetIdValue(entry).Equals(keyValue));
DbContext.Entry(local).State = EntityState.Detached;
DbContext.Entry(t).State = EntityState.Modified;
}
感谢@Crowcoder 和@DavidBrowne-Microsoft 的回复让我找到了这个解决方案。
我的应用程序遇到了这个已知问题。 我尝试过使用 HasKey 和 HasAlternateKey 进行很多更改,甚至是 HasIndex、Unique 和 OnModelCreateCreating() 方法的其他变体。 我什至重新映射了我的实体,但仍然没有成功!
The instance of entity type 'Imoveis' cannot be tracked because another instance with the key value '{Cod: 91}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
我的 BaseRepository 的我的 Update() 方法 class:
public T Update(T entity)
{
DbContext.Entry(entity).State = EntityState.Modified; <-- Exception happens here
DbContext.SaveChanges();
return entity;
}
如何调用 Update()。这个问题发生在两个电话上。第二次尝试是防止此错误的失败方法:
public Imoveis InsertOrUpdateUniqueName(Imoveis imoveis)
{
try
{
if (imoveis.Cod > 0)
Update(imoveis);
else
Insert(imoveis);
return imoveis;
}
catch (Exception ex)
{
if (imoveis.Cod > 0)
{
if (ex is DbUpdateException)
{
if ((ex.InnerException as SqlException)?.Number == 2627)
return UpdateImovelDuplicado(imoveis);
}
else if (ex is InvalidOperationException)
{
var local = DbContext
.Set<Imoveis>()
.Local
.FirstOrDefault(x => x.Cod.Equals(imoveis.Cod));
if (local != null)
DbContext.Entry(local).State = EntityState.Detached;
return Update(imoveis);
}
}
throw ex;
}
}
已解决!
解决方案:
1 - 在我的案例(控制台应用程序)中,我删除了异步插入或更新,因为我使用了单例 DbContext。但这不是强制性的,视情况而定。您需要了解 DbContext 的生命周期。
2 - 我更改了 Update() 方法以从 DbContext Set 集合中恢复和分离原始对象。
这是我的新 Update() 方法,为通用对象调用新的 DetachLocal() 方法。
public T Update(T entity)
{
DetachLocal(entity);
DbContext.SaveChanges();
return entity;
}
public void DetachLocal(T t)
{
var keyname = GetIdName(t);
var keyValue = GetIdValue(t);
var local = DbContext.Set<T>()
.Local
.FirstOrDefault(entry => GetIdValue(entry).Equals(keyValue));
DbContext.Entry(local).State = EntityState.Detached;
DbContext.Entry(t).State = EntityState.Modified;
}
感谢@Crowcoder 和@DavidBrowne-Microsoft 的回复让我找到了这个解决方案。