1

我在數據庫中添加了一行,並返回一個不同的上下文來更新它。我有這個類:實體框架更新現有對象

public abstract partial class DataManager<I, C> 
    where C : class, IDomainObject, I, new() where I : IDomainObject 

C可能是一個EntityObject,但這個類不知道。

我保存看起來是這樣的:

public virtual bool Save(I _item) 
    { 
     bool rc = true; 
     try 
     { 
     var set = m_Context.GetObjectSet<I, C>(); 
     ObjectStateEntry stateEntry = null; 
     if(! m_Context.ObjectStateManager.TryGetObjectStateEntry((C) _item, out stateEntry)) 
     { 
      if(_item is EntityObject) 
      { 
        if (_item.IsNew) 
        { 
         set.AddObject((C) _item); 
        } 
        else 
        { 
         try 
         { 
          set.Attach((C) _item); 
         } 
         catch(Exception ex) 
         { 
          set.ApplyCurrentValues((C) _item); 
         } 

等等...

在我的測試情況下,stateEntry不TryGetObjectStateEntry發現。然而,它是一個EntityObject,它不是新的(IsNew是我的標誌),所以它到達了其他地方。這裏是我的問題:set.Attach拋出這個錯誤

「ObjectStateManager中已存在具有相同鍵的對象,ObjectStateManager無法使用相同鍵追蹤多個對象。

,並在第二天瞬間,ApplyCurrentValues拋出這樣一句:

「與所提供的對象的密鑰匹配無法在ObjectStateManager找到一個關鍵的對象驗證提供的鍵值。對象匹配必須應用更改的對象的鍵值。「

這些都是真的嗎?

更多信息:

_item被在另一背景下獲得創建。隨後處理了這一背景。此時,_item有一個EntityState.Unchanged。我對它進行了一些更改,並更改爲EntityState.Modified。 (我沒有想到,因爲上下文(及其ObjectStateManager)應該已經消失。)無論如何,一旦它到達Save(上),它的狀態(由調試器報告)就會被修改,但是我有一個新的背景。如果我在此處獲得所有ObjectStateEntries(已添加,已刪除,已修改,未更改)的列表,則只有兩個,_item不是ApplyCurrentValues報告的其中一個,但它不能被附加,因爲「它是也在那裏!「。也許問題在於它仍然附加到一箇舊的ObjectStateManager(可能有一些引用不會讓ObjectStateManager處置?)。

+0

你在調用context.SaveChanges()兩次嗎? –

+0

@DannyVarod - 我正在使用UnitOfWork,在處理單元時我只調用SaveChanges,並且同時處理上下文。這是一個網絡應用程序,因此它的上下文生命週期非常短。 WcfService已經用完UnitOfWork來獲得_item(即我提到的「獲取另一個上下文」)。但是一旦我們開始保存,SaveChanges就沒有機會被調用兩次了。 –

+0

你確定你沒有從你的依賴注入框架獲得兩次相同的Uow嗎? –

回答

0

問題是每次db-context被初始化時,它都會從數據庫和foreach行中獲取行,分配一個實體鍵。這意味着同一行,由2個數據庫上下文檢索將有2個不同的實體鍵。實體鍵就像實體框架中的一個id,它被用來代替實體的ID。但是表的約束雖然保留(沒有重複的主鍵) 希望這是有道理的。

+0

答案是有道理的,但問題是,如何通過Attach將其報告爲「已存在」並將ApplyCurrentValues報告爲「找不到」? –

+0

我真的不知道是什麼導致第二個問題。但試着解決第一個問題,這可能與第二個問題有關。我建議(快速測試)您使用靜態的dbcontext – Boomer

0

問題是,您將兩個不同的用戶連接到相同的組織,但是,組織對象在每種情況下都是不同的實例。

如果該組織已經在數據庫中,請嘗試:

  1. 無論是導航屬性設置爲組織設置爲null,只設置OrganizationId屬性。

  2. 或從數據庫中加載組織實體並將其放置在導航道具中。

如果組織沒有在DB:

使用相同的實例(扔一個離開,並與其他替代它)。