2013-04-05 3 views
3

У меня есть следующий код:Удалить объект с соответствующими субъектами в EntityFramework

[HttpPost] 
public ActionResult Eliminar(Usuario usuario) 
{ 
     db.Usuarios.Attach(usuario); 
     usuario.Transacciones.ToList().ForEach(t => db.Transacciones.Remove(t)); 
     usuario.Eventos.ToList().ForEach(e => db.Eventos.Remove(e)); 
     db.Usuarios.Remove(usuario); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
} 

Я не могу заставить его работать. Я знаю, что для удаления сущности, которую вы сначала должны ее прикрепить, она не работает для объекта, который имеет отношения. Я также попытался сделать цикл foreach и прикреплять каждый объект Transaccion и Evento, прежде чем удалять их, но он не работает.

Это ошибка InnerException содержит:

System.Data.SqlClient.SqlException: The DELETE statement conflicted with the REFERENCE constraint "FK_TR_US". The conflict occurred in database "bd_dm", table "dbo.Transacciones", column 'idUsuario'. The statement has been terminated.

Я знаю, что это значит, но я не знаю, как сделать код работы. Мне нужно сначала удалить все Transacciones и Eventos, связанные с Usuario, чтобы удалить Usuario.

+0

Включена ли в комплекте ленивая загрузка? Я имею в виду: 'usario.Transacciones.ToList()' возвращает правильные строки? –

+0

Попробуйте вызвать 'SaveChanges()' _before_, удалив 'Usario', после чего снова вызываем' SaveChanges'. Или включите RI в базе данных. –

+0

@NicholasButler, я загружаю его с помощью Usuario usuario = db.Usuarios . Включить («Транзакционные») . Включить («Eventos») . Где (u => u.id == id) .Single(); –

ответ

3

После много отладки (на удаленном сервере) я выяснил, в чем проблема. Usuario usuario данные переданы в метод Eliminar правильно, но связанные объекты нет. Поэтому я должен загрузить их, прежде чем удалять их, а затем удалить объект Usuario.

Это мой окончательный код:

[HttpPost] 
public ActionResult Eliminar(Usuario usuario) 
{ 
    db.Usuarios.Attach(usuario); 
    db.Entry(usuario).Collection("Transacciones").Load(); 
    db.Entry(usuario).Collection("Eventos").Load(); 

    usuario.Transacciones.ToList().ForEach(t => db.Transacciones.Remove(t)); 
    usuario.Eventos.ToList().ForEach(e => db.Eventos.Remove(e)); 
    db.Usuarios.Remove(usuario); 
    db.SaveChanges(); 

    return RedirectToAction("Index"); 
} 
1

Это, вероятно, не поможет, но может помочь тем, кто видит это (как я сделал, исследуя эту проблему).

Выполнение комбинации foreach/remove, которую вы делаете выше, не требуется, если в базе данных установлена ​​настройка «каскад при удалении». Есть несколько способов сделать это, но в этой главе в «Программирующей структуре Entity Framework: Code First» https://www.safaribooksonline.com/library/view/programming-entity-framework/9781449317867/ch04s04.html это очень хорошо объясняется.

В вашем случае выше:

usuario.Transacciones

usuario.Eventos

Просто зайдите в класс этой ассоциации, и на обратном ключе (вероятно, в этом случае, общественных виртуальных Юзеры ;, в классе ассоциаций) добавьте декоратор [Обязательный], который изменит внешний ключ таким образом, чтобы он имел каскад при удалении.

Если вы этого не сделаете, эти ассоциации будут установлены в значение null вместо удаления.

Смежные вопросы