2014-05-23 106 views
3

,我有以下數據模型:更新許多到許多協會GraphDiff

Data Model

我的商業邏輯與分離的實體的作品,所以我使用GraphDiff進行更新。我在更新PerfModes/CalcPoints關聯時遇到問題。概念上,Block擁有CalcPoints和PerfModes,但CalcPoints可以與任意數量的PerfModes關聯。

我正在嘗試在塊級別執行更新。我提出的代碼不會拋出任何錯誤(而其他嘗試),但它也不會更新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調用,但是最好的辦法是將它們分開?

Here's與相關的代碼和失敗的單元測試的要點。

我繼承EF生成的容器類來創建禁用代理創建的我自己的上下文。這會導致GraphDiff出現問題嗎?

+0

我會研究它,但我不願意鍵入所有的類,上下文等。你能否發佈你的整個代碼 - 包括一個**失敗的**單元測試 - *某處*(我想它只是將代碼粘貼到問題中)? [gist](https://gist.github.com/)也許.. – andyp

+0

我在問題中添加了一個要點。 – Matt

+0

只是一個快速更新:如果您刪除'.AssociatedEntity(f => f.CalcPoint)'一切按預期工作。我打算調試爲什麼這個關聯會導致問題,因爲我認爲它不應該 - 如果它是GraphDiff中的錯誤,我會修復它.. – andyp

回答

2

當你的映射似乎是正確的,我試圖重現您的問題是這樣的:

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

所有實體簡單波蘇斯與一個int鍵,只是IDbSet<T>sDbContext。我沒有通過流暢的API在OnModelCreating(..)中添加任何內容,也沒有使用導航屬性中的任何屬性。

我上面的代碼工作正常,所以我有一些建議/問題:

  • 什麼(顯著),您做了不同的我,然後上面?
  • 您是否在UpdateGraph()之後致電SaveChanges()?這不是暗示的!
  • 你有最新版本的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)) 
); 
+0

看我的編輯。也許我需要將代碼分解成多個UpdateGraph調用? – Matt