EFCore 修改DbSet状态或者Attach()时,抛出异常:另一个相同ID的实体已被跟踪
异常信息
System.InvalidOperationException
The instance of entity type 'xxx' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
原因
前一次查询出来被缓存在本地了,不允许再次将一个状态为Dettach的实体转为跟踪状态
处理办法
将 DbContext.Set<T>().Local
里的相同ID的已跟踪数据设置为 Dettach
状态即可
这里写了个拓展方法,懒的同学自己拷贝
public static class DbContextExtensions
{
public static void DetachWhenExist<TEntity>(this DbContext dbContext, Func<TEntity, bool> predicate) where TEntity : class
{
var local = dbContext.Set<TEntity>().Local.FirstOrDefault(predicate);
if(local is not null)
{
dbContext.Entry(local).State = EntityState.Detached;
}
}
}
PS
找问题过程中,尝试时发现,在调用 Attach(en)
方法时,抛出异常,如果把这段代码放到 try 块,捕获后再执行一次 Attach(en)
,就可以正常执行。