簡體   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