#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) Присоединяю родительский объект последним, без связанных с ним «дочерних объектов». Я обновил вопрос своим функциональным кодом.