2011-10-29 29 views
1

我有一個名爲Message的模型。在該模型中,有一個名爲Resource的另一個模型的ICollection ResourceSubscribers。當我嘗試一個實體對象不能被IEntityChangeTracker的多個實例引用

public void SaveMessage(List<int> subscribers) 
    { 
     Condition.Requires(model).IsNotNull(); 
     Message model = new Message(); 

     //Some assignments to initialize the model 

     ICollection<Resource> res = new List<Resource>(); 

     foreach (var item in subscribers) 
     { 
      res.Add(this.ResourceService.GetResourceById(item)); 
     } 

     model.ResourceSubscribers = res; 
     Context.Messages.Add(model); 
     Context.SaveChanges(); 
    } 

「Context.Messages.Add(model);」行引發一個InvalidOperationException異常消息「一個實體對象不能被多個IEntityChangeTracker實例引用」。

回答

0

您是否使用GetResourceById中的另一個上下文獲取資源?在那種情況下,這些對象與該上下文相關聯。在做Context.Messages.Add時,您嘗試將對象與不允許的另一個上下文關聯。

所有發生在一起的相關操作應該使用相同的上下文。在周圍有多個上下文需要問題。

+0

感謝您的回答。 public void SaveMessage(List subscribers) Condition.Requires(model).IsNotNull();消息模型= new Message(); //初始化模型的一些作業 ICollection res = new List (); foreach(var訂閱者中的項目) { res.Add(this.Context.Resources.Find(item)); } model.ResourceSubscribers = res; Context.Messages.Add(model); 上下文。保存更改(); } 爲我工作。 – dload

+0

@dload:如果這是幫助您解決問題的答案,則應通過單擊複選標記將其標記爲已接受。 –

2

如果您使用相同的上下文任何地方更好地使用上下文作爲單例實例。

這將確保一個類只有一個實例,並給它提供一個全局訪問點

檢查:http://www.dofactory.com/Patterns/PatternSingleton.aspx#_self1

+0

看到一個答案我在過去: '基本上,我會建議爲每個工作單元創建一個新的上下文'http://stackoverflow.com/questions/14359297/execution-of-the-command-requires-an -open和可用的連接最connecti –

0

這是一個老問題,但我想我會發布我的答案的情況下,它有助於某人。

我在MVC代碼中遇到了同樣的問題,即使使用Elad Benda提到的工作單元模式。我發現我的DbContext資源在控制器調用結束時沒有被釋放。

using (_DatabaseUow) 
    { 
     // your controller code that accesses the database here. 
    } // When this goes out of scope dispose is called. 

然後清除DatabaseUnitOfWork類

public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing == true) 
     { 
      _ObdDbContext.DetachAll(); 
      _ObdDbContext = null; 
      _ObdBusinessData = null; 
     } 
    } 

    ~DatabaseUnitOfWork() 
    { 
     Dispose(false); 
    } 

的_ObdBusinessData構件類似的存儲庫。最後,在的DbContext派生類中DetachAll()方法是這樣的:

public void DetachAll() 
    { 
     var entries = SetTestsOnlineData.Local; 
     while (entries.Count != 0) 
     { 
      TestsOnlineData tod = entries[0]; 
      Tests tro = entries[0].Tests; 
      List<TestsDtc> dtcs = entries[0].Tests.TestsDtcs.ToList(); 

      foreach (TestsDtc dtc in dtcs) 
       Detach(dtc); 
      Detach(entries[0].Tests); 
      Detach(entries[0]); 

      tro.TestsDtcs = dtcs; 
      tro.TestsOnlineData = tod; 
      tod.Tests = tro; 
     } 
    } 

    public void Detach(object entity) 
    { 
     ((IObjectContextAdapter)this).ObjectContext.Detach(entity); 
    } 

我用我的實體/對象的特定知識脫離內存中的所有。我有一個名爲TestsOnlineData的表。它鏈接到鏈接到TestsDtc列表的測試。注意,我保留了這些鏈接關係,因爲我的對象樹的根將被保留,但是當它們被分離時,DbContext會釋放其他的鏈接關係。

我本來想讓這個更通用,但這個工作。我希望這有幫助。

相關問題