【问题标题】:Many-to-Many Delete/Remove failing w/ "An object with the same key already exists in the ObjectStateManager"多对多删除/删除失败 w/“ObjectStateManager 中已存在具有相同键的对象”
【发布时间】:2013-08-21 17:10:55
【问题描述】:

总结:使用 .attachto 的多个多对多关系添加工作正常,但相同的代码,除了是 .remove,而不是 .add,会导致可怕:

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)

然后我在第二次删除尝试时收到错误。

那么让我困惑的是:为什么我在.add'ing时可以成功.attachto多个“trainer”,但在.remove'ing时却不行?

任何建议将不胜感激。

【问题讨论】:

  • 虽然我在下面发布了一个工作,但如果有人愿意分享他们的见解,我仍然很想知道这个问题的答案。谢谢。

标签: asp.net entity-framework many-to-many entity-framework-5


【解决方案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 的问题,然后崩溃当我删除实体 Trainer 时退出。

通过首先循环遍历相关培训师的表格并将它们添加到列表中,然后我可以通过循环遍历列表来成功删除它们(我不能直接在表格循环中删除它们,因为这会出错带有“集合已修改;枚举操作可能无法执行。”的循环。

希望有一天这对某人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多