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不会分离,只是将状态标记为未更改。