使用GraphDiff更新多对多关联

我有以下数据模型:

数据模型

我的业务逻辑适用于分离的实体,所以我使用GraphDiff来执行更新。 我在更新PerfModes / CalcPoints关联时遇到问题。 从概念上讲,Block拥有CalcPoints和PerfModes,但CalcPoints可以与任意数量的PerfModes相关联。

我正在尝试在Block级别进行更新。 我提出的代码不会抛出任何错误(而其他尝试也会),但它也不会更新PerfModes / CalcPoints关联。

container.UpdateGraph(block, map => map .OwnedCollection(b => b.HistPoints) .OwnedCollection(b => b.CalcPoints) .OwnedCollection(b => b.PerfModes, with => with .OwnedCollection(p => p.FilterCriterion, with2 => with2 .OwnedCollection(fc => fc.Filters, with3 => with3 .AssociatedEntity(f => f.OperatorType) .AssociatedEntity(f => f.CalcPoint)))) .AssociatedCollection(p => p.CalcPoints) ); 

我可能没有完全掌握EF图和GraphDiff。 如何确保多对多PerfModes / CalcPoints关联正确更新?

编辑

在查看了andyp的答案后,我从GitHub中下载了最新版本的GraphDiff并尝试了以下映射:

 container.UpdateGraph(block, map => map .OwnedCollection(b => b.CalcPoints) .OwnedCollection(b => b.PerfModes, with => with.AssociatedCollection(pm => pm.CalcPoints))); 

这正确地更新了我的PerfModes / CalcPoints关联。 我切换回原始映射,仍然看到关联的问题没有更新,所以似乎尝试立即更新整个模型有问题。 我可以使用多个UpdateGraph调用,但是什么是最好的方法来解决它们?

这是一个带有相关代码和失败unit testing的要点。

我正在inheritanceEF生成的容器类来创建我自己的上下文,禁用代理创建。 这会导致GraphDiff出现问题吗?

由于您的映射似乎是正确的,我试图像这样重现您的问题:

 var calcPoint = new CalcPoint(); var block = new Block { CalcPoints = new List {calcPoint}, PerfModes = new List { new PerfMode {CalcPoints = new List {calcPoint}} } }; using (var context = new TestDbContext()) { context.UpdateGraph(block, map => map .OwnedCollection(b => b.CalcPoints) .OwnedCollection(b => b.PerfModes, with => with.AssociatedCollection(pm => pm.CalcPoints))); context.SaveChanges(); } using (var context = new TestDbContext()) { var reloaded = context.Blocks.Include("PerfModes.CalcPoints").Single(); Assert.AreEqual(1, reloaded.CalcPoints.Count); Assert.AreEqual(1, reloaded.PerfModes.Count); Assert.AreEqual(1, reloaded.PerfModes[0].CalcPoints.Count); Assert.AreEqual(reloaded.CalcPoints[0], reloaded.PerfModes[0].CalcPoints[0]); } 

所有实体都是简单的POCO,在我的DbContext上有一个int键和IDbSets 。 我既没有通过流畅的API在OnModelCreating(..)添加任何内容,也没有在导航属性上使用任何属性。

我上面的代码工作正常,所以我有几个建议/问题:

  • 什么 (重要的)你做的不同于我吗?
  • 你在UpdateGraph()之后调用SaveChanges() UpdateGraph()吗? 这并不暗示!
  • 你有最新版的GraphDiff吗? 请注意,NuGet包已经过时了,最好从Github获取当前源代码并自行构建。
  • 如果您的问题仍然存在,请使用无效的确切方案更新您的问题:请在调用UpdateGraph()之前包括DbContext的状态,您希望GraphDiff进行的更改以及无法进行的更改。

编辑 :你的映射毕竟不正确,你要映射Block.CalcPoints 两次 ,一次作为拥有的集合(第一次调用OwnedCollection(..) ),一次作为关联集合(最后一次只调用AssociatedCollection(..) )。 因此,您从未告诉GraphDiff映射PerfModes.CalcPoints ,反过来,它永远不会更新该集合.. 😉

要让GraphDiff这样做,请从最后一行之前的行末尾移动到最后一行的末尾,你应该没问题(之后你的缩进与括号匹配)。 正确的映射看起来像这样(最后一行末尾有两个右括号):

 container.UpdateGraph(block, map => map .OwnedCollection(b => b.HistPoints) .OwnedCollection(b => b.CalcPoints) .OwnedCollection(b => b.PerfModes, with => with .OwnedCollection(p => p.FilterCriterion, with2 => with2 .OwnedCollection(fc => fc.Filters, with3 => with3 .AssociatedEntity(f => f.OperatorType) .AssociatedEntity(f => f.CalcPoint))) .AssociatedCollection(p => p.CalcPoints)) );