实体框架 6 - 附加使用 AsNoTracking 查询的实体图



我正在从表FattureFornitori中检索实体列表,并加载它们拥有的集合(Voci,复数形式 - Voce,单数形式(以及每个VoceTipoCosto实体的引用:

var db = new DbGestPre();
db.Configuration.ProxyCreationEnabled = false;
var s = db.FattureFornitori
.Include(x => x.Voci)
.Include(x => x.Voci.Select(y => y.TipoCosto))
.AsNoTracking().ToList();

现在,单个FattureFornitori中的多个Voci可以引用同一TipoCosto。 因此,当我尝试将单个FattureFornitori与其 Voci 和引用的TipoCosto附加时,我遇到以下错误:

System.InvalidOperationException: 'Attaching an entity of type 'GP.Model.TipoCosto' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.'

对一个 FattureFornitori 实体(此处名为 ff(进行的一些调试显示:

ff.Voci[1].IdTipoCosto == ff.Voci[0].IdTipoCosto
true
ff.Voci[1].TipoCosto == ff.Voci[0].TipoCosto
false

因此,实体框架为同一实体创建多个实例!因此,附加方法引发的错误是有意义的。 但是如何解决这种情况呢? 我照顾了GraphDiff和其他类似的工具,但它们无能为力。 有什么提示吗? 谢谢!!

正如 Gert Arnold 所建议的那样,一种解决方法是删除 AsNoTracking((。 但这意味着数据库上下文会将所有实体添加到跟踪的实体中,因此性能会很差。

我尝试了以下代码:

var db = new DbGestPre();
db.Configuration.ProxyCreationEnabled = false;
db.Configuration.AutoDetectChangesEnabled = false;
var s = db.FattureFornitori
.Include(x => x.Fornitore)
.Include(x => x.Voci)
.Include(x => x.Voci.Select(y => y.TipoCosto));
List<FatturaFornitore> data = s.ToList();
db.Dispose();

为了快速将实体与上下文分离,我处置了上下文。欢迎任何更快/更好的方法。 此代码在 858 毫秒内运行。

我以前的选择

var db = new DbGestPre();
db.Configuration.ProxyCreationEnabled = false;
var s = db.FattureFornitori
.Include(x => x.Fornitore)
.Include(x => x.Voci)
.Include(x => x.Voci.Select(y => y.TipoCosto))
.AsNoTracking();
List<FatturaFornitore> data = s.ToList();

仅用了 500 毫秒就跑了。

所以我仍在寻找一种方法来使这个版本的代码与 AsNoTracking 一起工作。

最新更新