简体   繁体   English

使用GraphDiff更新多对多关联

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

I have the following data model: 我有以下数据模型:

数据模型

My business logic works with detached entities so I'm using GraphDiff to perform updates. 我的业务逻辑适用于分离的实体,所以我使用GraphDiff来执行更新。 I'm having trouble updating the PerfModes/CalcPoints association. 我在更新PerfModes / CalcPoints关联时遇到问题。 Conceptually, Block owns CalcPoints and PerfModes, but CalcPoints can be associated with any number of PerfModes. 从概念上讲,Block拥有CalcPoints和PerfModes,但CalcPoints可以与任意数量的PerfMode相关联。

I'm trying to do updates at the Block level. 我正在尝试在Block级别进行更新。 The code I came up with doesn't throw any errors (while other attempts did) but neither does it update the PerfModes/CalcPoints association. 我提出的代码不会抛出任何错误(而其他尝试也会),但它也不会更新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)
);

I probably don't have a full grasp of EF graphs and GraphDiff. 我可能没有完全掌握EF图和GraphDiff。 How do I ensure that the many-to-many PerfModes/CalcPoints association gets updated correctly? 如何确保多对多PerfModes / CalcPoints关联正确更新?

EDIT 编辑

After looking over andyp's answer, I pulled down the latest version of GraphDiff from GitHub and tried the following mappings: 在查看了andyp的答案后,我从GitHub中下载了最新版本的GraphDiff并尝试了以下映射:

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

This correctly updates my PerfModes/CalcPoints association. 这正确地更新了我的PerfModes / CalcPoints关联。 I switched back to my original mappings and still saw the issue of the association not updating, so it seems there's a problem with trying to update the entire model at once. 我切换回原来的映射,仍然看到关联没有更新的问题,所以似乎尝试立即更新整个模型有问题。 I'd be fine with making multiple UpdateGraph calls, but what would be the best way to break them out? 我可以使用多个UpdateGraph调用,但是什么是最好的方法来解决它们?

Here's a gist with relevant code and a failing unit test. 这是一个带有相关代码和失败单元测试的要点。

I'm inheriting the EF generated container class to create my own context with proxy creation disabled. 我正在继承EF生成的容器类来创建我自己的上下文,禁用代理创建。 Does that cause a problem with GraphDiff? 这会导致GraphDiff出现问题吗?

As your mappings seemed to be correct, I've tried to reproduce your issue like this: 由于您的映射似乎是正确的,我试图像这样重现您的问题:

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]);
}

All entities are simple POCOs with an int key and just IDbSet<T>s on my DbContext . 所有实体都是简单的POCO,在我的DbContext上有一个int键和IDbSet<T>s I've neither added anything in OnModelCreating(..) via the fluent API nor used any attributes on the navigation properties. 我既没有通过流畅的API在OnModelCreating(..)添加任何内容,也没有在导航属性上使用任何属性。

My code above is working properly, so I've got a couple of suggestions / questions: 我上面的代码工作正常,所以我有几个建议/问题:

  • Is there anything (significant) you did differently then me above? 什么 (重要的)你做的不同于我吗?
  • Do you call SaveChanges() after UpdateGraph() ? 你在UpdateGraph()之后调用SaveChanges() UpdateGraph()吗? It's not implied! 这并不暗示!
  • Do you have the latest version of GraphDiff? 你有最新版的GraphDiff吗? Please note, that the NuGet package is quite outdated, it's better to grab the current source from Github and build it yourself. 请注意,NuGet包已经过时了,最好从Github获取当前源代码并自行构建。
  • If your problem persists please update your question with the exact scenario that isn't working: please include the state of your DbContext before calling UpdateGraph() , the changes you expect GraphDiff to make and the ones it fails to make. 如果您的问题仍然存在,请使用无效的确切方案更新您的问题:请在调用UpdateGraph()之前包括DbContext的状态,您希望GraphDiff进行的更改以及无法进行的更改。

EDIT : Your mapping wasn't correct after all, you're mapping Block.CalcPoints twice , once as an owned collection (first call to OwnedCollection(..) ) and once as an associated collection (last and only call to AssociatedCollection(..) ). 编辑 :你的映射毕竟不正确,你将Block.CalcPoints映射两次 ,一次作为拥有的集合(第一次调用OwnedCollection(..) ),一次作为关联集合(最后一次只调用AssociatedCollection(..) )。 So you never told GraphDiff to map PerfModes.CalcPoints and it, in turn, never updates that collection.. ;-) 因此,您从未告诉GraphDiff映射PerfModes.CalcPoints ,反过来,它永远不会更新该集合.. ;-)

To ask GraphDiff to do that please move one ) from the end of the line before the last line to the end of the last line and you should be fine (after that your indentation matches the brackets). 要问GraphDiff做请将一)从行的末尾最后一行最后一行结束前,你应该罚款(即你的缩进括号匹配之后)。 The correct mapping looks like this (two closing brackets at the end of the last line): 正确的映射看起来像这样(最后一行末尾有两个右括号):

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