我正在从表const handleClick = event => {
// debugger
setName(event.target.id);
setId(event.target.getAttribute("name"));
};
中检索实体列表,还将它们所拥有的集合(Voci,复数形式-Voce,单数形式)以及从每个FattureFornitori
的引用加载到Voce
实体:
TipoCosto
现在,单个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();
中的多个Voci
可以引用相同的FattureFornitori
。
因此,当我尝试将单个TipoCosto
附加到其Voci和引用的FattureFornitori
时,会遇到以下错误:
TipoCosto
对该FattureFornitori实体(此处称为ff)进行的一些调试显示:
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.'
因此,实体框架为同一实体创建多个实例!因此,attach方法引起的错误是有道理的。 但是如何解决这种情况呢? 我照顾了GraphDiff和其他类似工具,但它们无济于事。 有什么提示吗? 谢谢!
答案 0 :(得分:1)
正如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能够运行此版本代码的方法。