我有一个很大的代码库,但是不幸的是,我无法用一个小的代码示例来重现它,但是我可以这样做:
db.Persons.Add(new Person() {Name = "Foo"});
await db.SaveChangesAsync()
await db.Persons.FromSql("truncate table Persons;select top 0 * from Persons").ToListAsync();
db.Persons.Add(new Person() {Name = "Bar"});
await db.SaveChangesAsync()
最后一次保存更改时出现此错误:
System.InvalidOperationException:无法跟踪实体类型'InstructionLineAllocationDto'的实例,因为已经跟踪了另一个具有相同键值的{'Id'}实例。
我知道截断有点不标准。错误中的Id字段是我不太关心的数据库中的Identity字段。
我找不到任何地方解释如何实现登台表,在该表中您经常截断并插入一堆,并且如果每个tuncate运行一次,此代码也不会成为问题。 (但这是一个始终处于活动状态的侦听器)
所有永久运行的答案有时会插入很多内容并进行截断,但始终保持活跃很有趣。
但是我最具体的问题是我如何在没有任何变更跟踪的情况下做到这一点
代码是EntityFrameworkCore SqlServer 2.0.0
答案 0 :(得分:0)
我不确定到底是怎么回事,但看起来ID保持为负数循环。正如Pac0所写,然后的解决方案是派遣。因此,我的代码最终在DbContext中陷入困境
var changedEntriesCopy = _dbEntities.ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added ||
e.State == EntityState.Modified ||
e.State == EntityState.Deleted)
.ToList();
await _dbEntities.SaveChangesAsync();
foreach (var entry in changedEntriesCopy)
entry.State = EntityState.Detached;
更奇怪的是,当然,SaveChangesAsync也可以进行分离,如果在Save之后运行代码,则changedEntriesCopy包含0个条目。但是有了这段代码,问题就解决了。
我不了解某种实体框架魔术。