繁体   English   中英

使用GraphDiff更新多对多关联

[英]Update Many-to-Many Association with GraphDiff

我有以下数据模型:

数据模型

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

我正在尝试在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调用,但是什么是最好的方法来解决它们?

这是一个带有相关代码和失败单元测试的要点。

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

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

var calcPoint = new CalcPoint();
var block = new Block
{
    CalcPoints = new List<CalcPoint> {calcPoint},
    PerfModes = new List<PerfMode> 
    {
        new PerfMode {CalcPoints = new List<CalcPoint> {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键和IDbSet<T>s 我既没有通过流畅的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))
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM