简体   繁体   English

在EntityFramework中删除具有相关实体的实体

[英]Remove entity with related entities in EntityFramework

I have the following code: 我有以下代码:

[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");
}

I can't make it work. 我不能让它发挥作用。 I know that to delete an entity you first have to attach it, but it isn't working for an entity that has relations. 我知道删除一个实体首先必须附加它,但它不适用于有关系的实体。 I've also tried to do a foreach loop, and attaching each Transaccion and Evento entities before removing them, but it doesn't work neither. 我也试着做foreach循环,并连接各TransaccionEvento删除它们之前的实体,但它不工作也没有。

This is the error the InnerException contains: 这是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.

I know what that means, but I don't know how to make the code work. 我知道这意味着什么,但我不知道如何使代码工作。 I need to remove first all the Transacciones and Eventos related to the Usuario , to be able to remove the Usuario . 我需要删除首先是TransaccionesEventos相关Usuario ,能够去除Usuario

After a lot of debugging (in a remote server) I found out what the problem was. 经过大量调试(在远程服务器中)后,我发现了问题所在。 The Usuario usuario data is passed to the Eliminar method correctly, but the related objects are not. Usuario usuario数据正确传递给Eliminar方法,但相关对象不是。 So I have to load them before being able to remove them, and then remove the Usuario object. 所以我必须加载它们才能删除它们,然后删除Usuario对象。

This is my final code: 这是我的最终代码:

[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");
}

This probably won't help you , but may help those who see this (like I did when researching this problem). 这可能对你没有帮助,但可以帮助那些看到这个的人(就像我在研究这个问题时所做的那样)。

Doing the foreach/remove combination you're doing above isn't necessary if 'cascade on delete' is setup on the database. 如果在数据库上设置了“cascade on delete”,则无需执行上述正在进行的foreach / remove组合。 There are a few ways to do this, but this chapter in 'Programming Entity Framework: Code First' https://www.safaribooksonline.com/library/view/programming-entity-framework/9781449317867/ch04s04.html explains it very well. 有几种方法可以做到这一点,但“编程实体框架:代码优先”中的这一章https://www.safaribooksonline.com/library/view/programming-entity-framework/9781449317867/ch04s04.html解释得非常好。

In your case above: 在你的情况下:

usuario.Transacciones usuario.Transacciones

usuario.Eventos usuario.Eventos

Just go into that association's class, and on the reverse key (likely in this case, public virtual Usuarios;, in the associations' class) add the decorator [Required], which will change the foreign key such that it has cascade on delete. 只需进入该关联的类,并在反向键(可能在这种情况下,公共虚拟Usuarios;,在关联类中)添加装饰器[必需],这将更改外键,使其在删除时级联。

If you don't do this, those associations will be set to null instead of being removed. 如果不这样做,那些关联将被设置为null而不是被删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM