实体框架6-附加通过AsNoTracking查询的实体图 [英] Entity Framework 6 - Attaching a graph of entities queried with AsNoTracking
问题描述
我正在从表 FattureFornitori
中检索实体列表,并还加载它们所拥有的集合(Voci,复数形式-Voce,单数形式)和每个 Voce中的引用
到 TipoCosto
实体:
I am retrieving a list of entities from a table FattureFornitori
, and loading also a collection owned by them (Voci, plural form - Voce, singular form) and a reference from each Voce
to a TipoCosto
entity:
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
.因此,当我尝试使用其Voci和引用的 TipoCosto
附加单个 FattureFornitori
时,会遇到以下错误:
Now, multiple Voci
within a single FattureFornitori
can reference the same TipoCosto
.
So, when I try to attach a single FattureFornitori
with its Voci and the referenced TipoCosto
, I face the following error:
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)进行的一些调试显示:
Some debugging for that one FattureFornitori entity, here named ff, reveals:
ff.Voci[1].IdTipoCosto == ff.Voci[0].IdTipoCosto
true
ff.Voci[1].TipoCosto == ff.Voci[0].TipoCosto
false
因此,Entity Framework为同一实体创建多个实例!因此,attach方法引起的错误是有道理的.但是如何解决这种情况呢?我照顾了GraphDiff和其他类似工具,但它们无济于事.有什么提示吗?谢谢!
So Entity Framework creates multiple instances for the same entity! So the error raised by the attach method makes sense. But how to solve this situation?? I looked after GraphDiff and other tools like those but they cannot help. Any hint? Thanks!!
推荐答案
正如Gert Arnold所建议的,一种解决方法是删除AsNoTracking().但这意味着数据库上下文会将所有实体添加到被跟踪的实体中,因此会导致性能下降.
As Gert Arnold suggests, one workaround is to remove AsNoTracking(). But this means that the DB context will add ALL the entities to the tracked entities, so it will perform badly.
我尝试了以下代码:
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毫秒内运行.
To quickly detach the entities from the context, I Disposed the context. Any faster/better approaches are welcome. This code ran in 858ms.
我以前的选择
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能够运行此版本代码的方法.
So I am still looking for a way to make this version of the code with AsNoTracking working.
这篇关于实体框架6-附加通过AsNoTracking查询的实体图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!