【EFCore】修改DbSet状态或者Attach()时,抛出异常:另一个相同ID的实体已被跟踪

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 DettachWhenExist<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;
        }
    }
}

使用

xxxContext.DettachWhenExist<Student>(t=>t.Id == 2);

PS

找问题过程中,尝试时发现,在调用 Attach(en) 方法时,抛出异常,如果把这段代码放到 try 块,捕获后再执行一次 Attach(en),就可以正常执行。

posted @ 2021-10-21 18:54  wosperry  阅读(576)  评论(2编辑  收藏  举报