更新许多到许多协会GraphDiff [英] Update Many-to-Many Association with GraphDiff

查看:226
本文介绍了更新许多到许多协会GraphDiff的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下数据模型:





我的商业逻辑可以与分离的实体,所以我用GraphDiff进行更新。我无法更新PerfModes / CalcPoints关联。从概念上讲,阻止拥有CalcPoints和PerfModes,但CalcPoints可与任意数量PerfModes的关联。



我想在块级做更新。我想出了这个代码不抛出任何错误(而其他尝试做),但它也不更新PerfModes / CalcPoints关联。

  container.UpdateGraph(块地图= GT;图
.OwnedCollection(b = GT; b.HistPoints)
.OwnedCollection(b = GT; b.CalcPoints)
.OwnedCollection (b = GT; b.PerfModes,具有= gt;在
.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(块地图= GT;图
.OwnedCollection(b = GT; b.CalcPoints)
.OwnedCollection(b = GT; b.PerfModes,
与= > with.AssociatedCollection(PM => pm.CalcPoints)));

这正确更新我的PerfModes / CalcPoints关联。我转回到我原来的映射,并仍然认为联想没有更新的问题,所以它似乎有一个与试图一次更新整个模型的一个问题。 ?我会罚款进行多次UpdateGraph呼叫,但是这将是打破他们最好的出路。



这里的,提供相关的代码和一个失败的单元测试要点。



我继承了EF生成的容器类来创建自己的禁用代理创建上下文。这是否会导致GraphDiff问题?


解决方案

当你的映射似乎是正确的,我试图重现您的问题类似这样的:



<预类=郎-CS prettyprint-覆盖> VAR calcPoint =新CalcPoint();
VAR块=新座
{
CalcPoints =新的List< CalcPoint> {} calcPoint,
PerfModes =新的List< PerfMode>
{
新PerfMode {CalcPoints =新的List< CalcPoint> {calcPoint}}
}
};

使用(VAR上下文=新TestDbContext())
{
context.UpdateGraph(块地图= GT;图
.OwnedCollection(B = GT; b .CalcPoints)
.OwnedCollection(二= GT; b.PerfModes,
相= GT; with.AssociatedCollection(PM => pm.CalcPoints)));

context.SaveChanges();
}使用

(VAR背景=新TestDbContext())
{
VAR重装上阵= context.Blocks.Include(PerfModes.CalcPoints)。单( );
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]);
}



所有的实体是用int键和刚 IDbSet< T> S 我的的DbContext 。我既不是 OnModelCreating(..)通过流畅的API,也没有使用上的导航性能的任何属性。



添加任何东西

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




  • 是否有什么的(显著),您做了不同的话在我之上?

  • 请你叫的SaveChanges() UpdateGraph()?这不是暗示!

  • 请您有最新版本的GraphDiff的?请注意,那的NuGet包是较为陈旧,这是更好地抓住从 Github上电流源,并建立它你自己。

  • 如果您的问题仍然存在,请与的确切的不工作的情况更新你的问题:请包括状态的的DbContext 之前调用 UpdateGraph(),你还指望GraphDiff进行更改,也未能使的人。



修改
你映射不毕竟,你映射正确 Block.CalcPoints 两次后,曾经作为一家拥有集(第一个打电话给 OwnedCollection(..)),并曾作为关联集合(最后只有打电话 AssociatedCollection(..))。所以,你从来没有告诉过GraphDiff地图 PerfModes.CalcPoints ,它反过来,永远不会更新该集合..; - )



要问GraphDiff要做到这一点,请移动一个从该行的最后一行到最后一行结束前结束,你应该罚款(后您缩进括号匹配)。正确的映射看起来像这样(在最后一行的末尾两个闭合括号中):

  container.UpdateGraph(块,地图= GT;图
.OwnedCollection(b = GT; b.HistPoints)
.OwnedCollection(b = GT; b.CalcPoints)
.OwnedCollection(b = GT; b.PerfModes,与= gt;在
.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 have the following data model:

My business logic works with detached entities so I'm using GraphDiff to perform updates. I'm having trouble updating the PerfModes/CalcPoints association. Conceptually, Block owns CalcPoints and PerfModes, but CalcPoints can be associated with any number of PerfModes.

I'm trying to do updates at the Block level. The code I came up with doesn't throw any errors (while other attempts did) but neither does it update the PerfModes/CalcPoints association.

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. How do I ensure that the many-to-many PerfModes/CalcPoints association gets updated correctly?

EDIT

After looking over andyp's answer, I pulled down the latest version of GraphDiff from GitHub and tried the following mappings:

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. 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?

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. Does that cause a problem with 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. I've neither added anything in OnModelCreating(..) via the fluent API nor used any attributes on the navigation properties.

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()? It's not implied!
  • Do you have the latest version of GraphDiff? Please note, that the NuGet package is quite outdated, it's better to grab the current source from Github and build it yourself.
  • 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.

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(..)). So you never told GraphDiff to map PerfModes.CalcPoints and it, in turn, never updates that collection.. ;-)

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). 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))
);

这篇关于更新许多到许多协会GraphDiff的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆