C# 无变更跟踪的实体框架核心插入
我有一个很大的代码库,不幸的是,我不能用一个小的代码示例来重现它,但我有点这样做:C# 无变更跟踪的实体框架核心插入,c#,entity-framework-core,C#,Entity Framework Core,我有一个很大的代码库,不幸的是,我不能用一个小的代码示例来重现它,但我有点这样做: 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
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字段是数据库中的一个标识字段,我并不真正关心它
我找不到任何地方解释如何实现经常截断并插入一组的暂存表,如果每个tuncate运行一次,这段代码也不会成为问题。(但这是一个始终处于活动状态的侦听器)
所以,所有的答案都是永久运行的,插入很多,有时会截断,但总是活动的,这很有趣
但我最具体的问题是如何在没有任何变化跟踪的情况下做到这一点
代码是EntityFrameworkCore SQLServer2.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;
wierd部分是savechangesync当然也执行detatch,如果代码在保存之后运行,则changedEntriescope由0个条目组成。但有了这段代码,问题就解决了
有一种实体框架魔法我不明白。为什么选择top 0?您可以检查并取消跟踪所有实体,或者在截断后完全重新加载dbcontext。@Pac0代码只能通过数据库集访问SQL调用。由于它必须是生成真实实体的某个元素,然后选择0为空元素提供正确的属性,并且我使用truncate副作用来截断数据库表MMM,而不访问dbContext,我不知道如何分离Entities。据我所知,您可能无法在Add上使用“
AsNoTracking()
”。您能在之后尝试执行“SaveChanges()
”吗?这并不奇怪,因为SaveChanges不会分离,只是将状态标记为未更改。