c# - EntityFramework 更新实体失败 - 无法跟踪
问题描述
我的应用程序遇到了这个已知问题。我用 HasKey 和 HasAlternateKey 尝试了很多更改,甚至 HasIndex、Unique 和 OnModelCreateCreating() 方法的其他变体。我什至重新映射了我的实体,但仍然没有成功!
无法跟踪实体类型“Imoveis”的实例,因为已在跟踪另一个具有键值“{Cod: 91}”的实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。
我的 BaseRepository 类的 Update() 方法:
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 - In MY CASE (a console app), I removed async inserts or updates because I use a singleton DbContext. But this is NOT mandatory and depends on the case. You need to understand the life cycle of your DbContext.
2 - I changed my Update() method to recover and detach the original object from the DbContext Set collection.
This is my new Update() method calling a new DetachLocal() method for generic objects.
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;
}
Thanks to @Crowcoder and @DavidBrowne-Microsoft for the replies that put me in the way to find this solution.
推荐阅读
- sql - 外键作为复合主键的表的软删除实施失败
- kotlin - 使用 Kotlin 从字符串中的字符获取 unicode 值
- javascript - 当内部 div 为空时,如何隐藏 div?
- azure-devops - azure-devops-node-api:使用用户名和密码进行身份验证
- model - Committee Methods (ensemble learners) Best Model
- kubernetes - Magento CLI 设置,指定的实体类型无效:catalog_category
- javascript - JS Promise - 返回一些结果而不解决承诺
- css - 类名倒序
- ios - dyld:未加载库:@rpath/GoogleInteractiveMediaAds.framework/GoogleInteractiveMediaAds 自定义框架集成中的错误
- linux - 如何使用 Bash 收缩/收缩一组值