0

摘要:多​​個多對多關係添加使用.attachto可以很好地工作,但是具有相同的代碼作爲.remove而不是.add的例外會導致可怕:多對多刪除/刪除失敗w /「ObjectStateManager中已存在具有相同鍵的對象」

ObjectStateManager中已存在具有相同鍵的對象。 ObjectStateManager不能使用同一個鍵跟蹤多個對象。

所以這裏是代碼。基於表單字段,隱藏一個(具有以前的教練值),一個不是,我循環查看教練列表以查看哪一個已被選中或取消選定,然後添加或刪除客戶端與多對多關係之間的多對多關係教練:

Protected Sub dsClient_Updated(sender As Object, e As System.Web.UI.WebControls.EntityDataSourceChangedEventArgs) Handles dsClient.Updated 
    Dim Client As Client = e.Entity 
    Dim Trainers As IEnumerable(Of aspnet_Users), CurrentTrainer As String, PrevTrainer As String 

    ' Select list of Trainers 
    Trainers = From S In FitnessDB.aspnet_Users 

    For Each Trainer As aspnet_Users In Trainers 
     CurrentTrainer = Request.Form(Trainer.UserName) 
     PrevTrainer = Request.Form("Prev_" & Trainer.UserName) 
     ' Check if Trainer has been deleted 
     If CurrentTrainer = "" And PrevTrainer <> "" Then 
      ' Trainer previously existed, delete 
      FitnessDB.Detach(Trainer) 
      e.Context.AttachTo ("aspnet_Users", Trainer) 
      Client.aspnet_Users.Remove (Trainer) 
     ElseIf CurrentTrainer <> "" And PrevTrainer = "" Then 
      ' Doesn't exist, add 
      FitnessDB.Detach(Trainer) 
      e.Context.AttachTo ("aspnet_Users", Trainer) 
      Client.aspnet_Users.Add (Trainer) 
     End If 
    Next 
    e.Context.SaveChanges() 
End Sub 

我可以選擇多個教練添加就好了。它循環通過:

FitnessDB.Detach(Trainer) 
e.Context.AttachTo ("aspnet_Users", Trainer) 
Client.aspnet_Users.Add (Trainer) 

沒有問題,與新的關係添加就好了。如果我只刪除一個教練,它工作正常。但是,如果我嘗試使用下面

FitnessDB.Detach(Trainer) 
e.Context.AttachTo ("aspnet_Users", Trainer) <-- Error: An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key. 
Client.aspnet_Users.Remove (Trainer) 

代碼刪除多個訓練師,然後我得到第二刪除嘗試錯誤。

所以,我最爲困惑的是:爲什麼我可以成功.attachto多個「教練」時.add'ing,但不是when.remove'ing?

任何建議將不勝感激。

+0

雖然我已低於周圍的工作,我還是很想知道一個答案。如果任何人有洞察力,他們會分享,謝謝。 – Thom

回答

1

在這一點上,我得出了一個試探性的結論,認爲它是實體框架中的一個錯誤,原因有很多,我太累了,不想在這裏詳細討論。

但是我想出了一個解決方法。我已經刪除上面的代碼段是檢查教員刪除,代之以它:

For Each Trainer As aspnet_Users In Client.aspnet_Users 
    If Request.Form(Trainer.UserName) = "" Then DeleteTrainers.Add (Trainer) 
Next 
For Each Trainer As aspnet_Users In DeleteTrainers 
    Client.aspnet_Users.Remove (Trainer) 
Next 

整個子作爲改寫現在是:

Protected Sub dsClient_Updated(sender As Object, e As System.Web.UI.WebControls.EntityDataSourceChangedEventArgs) Handles dsClient.Updated 
    Dim Client As Client = e.Entity 
    Dim DeleteTrainers As New List(Of aspnet_Users), CurrentTrainer As String, PrevTrainer As String 

    ' Check for trainers that have been removed 
    For Each Trainer As aspnet_Users In Client.aspnet_Users 
     If Request.Form(Trainer.UserName) = "" Then DeleteTrainers.Add (Trainer) 
    Next 
    For Each Trainer As aspnet_Users In DeleteTrainers 
     Client.aspnet_Users.Remove (Trainer) 
    Next 

    ' Check for trainers to add 
    For Each Trainer As aspnet_Users In FitnessDB.aspnet_Users 
     CurrentTrainer = Request.Form(Trainer.UserName) 
     PrevTrainer = Request.Form("Prev_" & Trainer.UserName) 
     If CurrentTrainer <> "" And PrevTrainer = "" Then 
      ' Doesn't exist, add 
      FitnessDB.Detach(Trainer) 
      e.Context.AttachTo ("aspnet_Users", Trainer) 
      Client.aspnet_Users.Add (Trainer) 
     End If 
    Next 
    e.Context.SaveChanges() 
End 

通過轉向使用Client.aspnet_Users ,我能夠保持在相同的上下文(e.context)中,從而消除了必須從FitnessDB上下文重新附加到e.context的問題,e.context在刪除實體培訓師時崩潰了。

通過首先遍歷相關聯的培訓師表並將其添加到列表中,然後我可以通過循環列表成功地將其刪除(我無法直接在表循環中刪除它們,因爲那些錯誤脫離與環「集合被修改;枚舉操作可能不會執行。」

希望這可以幫助別人一天

相關問題