首页 新闻 赞助 找找看

EntityFramework 更新数据的时候报错

0
悬赏园豆:10 [待解决问题]
  MyDbContext dbContext = new MyDbContext();
            var result = dbContext.Test.AsNoTracking().FirstOrDefault(x => x.Id == 1);
            result.Title = "11111";
            dbContext.Update(result);
            dbContext.Entry<Test>(result).State = EntityState.Modified;
            dbContext.SaveChanges();


            var result1 = dbContext.Test.AsNoTracking().FirstOrDefault(x => x.Id == 1);
            result1.Title = "22222";
            dbContext.Update(result1);
            dbContext.Entry<Test>(result1).State = EntityState.Modified;
            dbContext.SaveChanges();

当更新同一个实体的时候报:The instance of entity type 'Test' 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.

Impossible的主页 Impossible | 初学一级 | 园豆:72
提问于:2020-04-27 15:14
< >
分享
所有回答(2)
0

很简单,在第一段和第二段之间加入
dbContext.Entry<Test>(result).State = EntityState.Untrack;

或者使用两个using(dbcontext){}别在同一个数据上下文

你用同一个数据上下文,
var result = dbContext.Test.AsNoTracking().FirstOrDefault(x => x.Id == 1);
result.Title = "11111";
dbContext.Update(result);
dbContext.Entry<Test>(result).State = EntityState.Modified;
dbContext.SaveChanges();
先不追踪的查出来了,然后更改,然后改变实体状态为追踪(Modified),此时你的实体状态已经是追踪状态了

然后你又来一遍,又查出来一个实体,也是追踪追踪状态

所以报错只能有一个追踪的实体去保存

猝不及防 | 园豆:2731 (老鸟四级) | 2020-04-27 15:36

明白原因了,我这里只是举了个项目中的例子,result和result1有可能是通过不同的查询条件得到的相同实体,而且Update都是封装的方法,每次调用这个方法后再声明一下 实体的 State 为EntityState.Untrack?

支持(0) 反对(0) Impossible | 园豆:72 (初学一级) | 2020-04-27 16:10

@Impossible:

换个思路,多次操作一个实体然后只保存一次

        yDbContext dbContext = new MyDbContext();
        var result = dbContext.Test.AsNoTracking().FirstOrDefault(x => x.Id == 1);
        result.Title = "11111";

        var result1 = result;
        result1.Title = "22222";
        dbContext.Update(result1);
        dbContext.Entry<Test>(result1).State = EntityState.Modified;
        dbContext.SaveChanges();
支持(0) 反对(0) 猝不及防 | 园豆:2731 (老鸟四级) | 2020-04-27 16:35

@Impossible:

声明一下 实体的 State 为EntityState.Untrack是可以的

每次用dbcontext的new一个其实也可以,没你想的那么严重

支持(0) 反对(0) 猝不及防 | 园豆:2731 (老鸟四级) | 2020-04-27 16:36

@猝不及防: DbContext是注入的,不能每次都new一个。而且这个Update(T entity),都是封装好的方法,在项目中result和result1不是每一次都相同,问题中的这个也只是举例。

支持(0) 反对(0) Impossible | 园豆:72 (初学一级) | 2020-04-27 17:13

@Impossible: 每次save完了你就把这个实体untrack,这不就统一了吗

支持(0) 反对(0) 猝不及防 | 园豆:2731 (老鸟四级) | 2020-04-27 17:20
0

在同一个 DbContext 实例中,被跟踪的实体只要 Key 相同,EF Core 就认为是同一个实体。

dudu | 园豆:31075 (高人七级) | 2020-04-27 15:37

有没有什么解决方法,我问题中只是举了个例子,现在明白什么原因了。
项目中有很多这种情况,先查询某条数据,更新这条数据的某个值,然后在修改传入的对象,查询的数据和要修改的对象可能Key会相同,这时Update的时候就会这样,因为DbContext都是注入的,也不能每次都实例化多次DbContext吧,这样处理肯定不好。

支持(0) 反对(0) Impossible | 园豆:72 (初学一级) | 2020-04-27 16:03

@Impossible: 既然是更新操作,为什么加 AsNoTracking()?直接让 EF 自动跟踪不是更好吗?

支持(0) 反对(0) dudu | 园豆:31075 (高人七级) | 2020-04-27 16:17

@dudu: 不加 AsNoTracking(),他们也是在同一个DbContext中更新的,也是会出现同样的问题。

支持(0) 反对(0) Impossible | 园豆:72 (初学一级) | 2020-04-27 16:20

@Impossible: 要去掉 EntityState.Modified

支持(0) 反对(0) dudu | 园豆:31075 (高人七级) | 2020-04-27 16:25

@dudu: 去掉也是报一样的错。

支持(0) 反对(0) Impossible | 园豆:72 (初学一级) | 2020-04-27 16:43
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册