Добавление связи с объектом, который находится в удаленном состоянии, не разрешено

#asp.net-mvc-3 #entity-framework-4.1 #dbcontext

#asp.net-mvc-3 #entity-framework-4.1 #dbcontext

Вопрос:

Я пытаюсь удалить ссылку на объект в отношении «Один ко многим» следующим образом, но получаю сообщение об ошибке при попытке прикрепить объект ‘o’ к моему DbContext. Ошибка:

«Добавление связи с объектом, который находится в удаленном состоянии, не разрешено».

Я также попробовал следующее вместо установки EntityState:

  _db.OrganizationMetrics.Remove(om)
  

Каков правильный способ удалить это?

 <HttpPost()>
Function Edit(ByVal ovm As OrganizationViewModel)

    Dim o As Organization


    o = AutoMapper.Mapper.Map(Of OrganizationViewModel, Organization)(ovm)

    For Each om In o.OrganizationMetrics
        _db.OrganizationMetrics.Attach(om)

        If om.Value = "removeMe" Then
            _db.Entry(om).State = EntityState.Deleted
        ElseIf om.Id = 0 Then
            _db.Entry(om).State = EntityState.Added
        Else
            _db.Entry(om).State = EntityState.Modified
        End If
    Next

    _db.Organizations.Attach(o) 'Error is thrown here

    If (ModelState.IsValid) Then

        _db.Entry(o).State = EntityState.Modified
        _db.SaveChanges()

        Return RedirectToAction("Index")
    Else

        Return View(ovm)
    End If

End Function
  

Обновить:

Это мой теперь функционирующий код. Ключ в том, чтобы не отображать дочерние объекты обратно в модель родительского объекта из модели представления, чтобы я мог работать с ними по отдельности.

     <HttpPost()>
    Function Edit(ByVal ovm As OrganizationViewModel)

        Dim o As Organization

        o = AutoMapper.Mapper.Map(Of OrganizationViewModel, Organization)(ovm) //The Automapper code ignores the OrganizationMetrics members
        _db.Organizations.Attach(o)

        For Each om In ovm.OrganizationMetrics
            _db.OrganizationMetrics.Attach(om)

            If om.Value = "removeMe" Then
                _db.Entry(om).State = EntityState.Deleted
            ElseIf om.Id = 0 Then
                _db.Entry(om).State = EntityState.Added
            Else
                _db.Entry(om).State = EntityState.Modified
            End If
        Next


        If (ModelState.IsValid) Then

            _db.Entry(o).State = EntityState.Modified
            _db.SaveChanges()

            Return RedirectToAction("Index")
        Else

            Return View(ovm)
        End If

    End Function
  

Ответ №1:

Когда вы присоединяете o с помощью _db.Organizations.Attach(o) , он просматривает все свои дочерние элементы и обнаруживает, что некоторые из них удалены. Когда он пытается присоединить их, вы получаете сообщение об ошибке, которое вы показываете. Это имеет смысл.

Сделайте шаг назад и выясните, что именно вы хотите сделать. Самый простой способ удалить что-либо — это получить это, а затем удалить. Что-то вроде:

 context.DeleteObject(context.MyEntity.Single(r => r.Id == myId));
  

Если вы хотите, вы можете издеваться над MyEntity объектом, используя только его ключ, а затем удалить этот объект, он также будет работать и сэкономит вам запрос выбора.

Комментарии:

1. Я думал, что это то, что «_db.OrganizationMetrics. Для меня подошло бы «Удалить (om)», но эта строка кода вызывает ту же ошибку. Что я пытаюсь сделать, так это перебрать объекты OrganizationMetric, которые были возвращены в ViewModel, и удалить все, что удалил пользователь (в этот момент они не удаляются из модели, просто помечены для удаления, чтобы я мог удалить их в контроллере)

2. То, что я в конечном итоге делаю, является многоступенчатым: 1) Я не сопоставляю дочерние объекты обратно с моделью родительского объекта 2) Я перебираю дочерние объекты в ViewModel, присоединяю их один за другим и добавляю или удаляю их из контекста по мере необходимости 3) Присоединяю родительский объект последним, без связанных с ним «дочерних объектов». Я обновил вопрос своим функциональным кодом.