实体框架 6:代码优先级联删除 [英] Entity Framework 6: Code First Cascade delete

查看:14
本文介绍了实体框架 6:代码优先级联删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,这里有几个类似的问题,但我仍然无法确定我在简化方案中究竟缺少什么.

So there are several similar questions on here to this, but I'm still having issues determing what exactly I'm missing in my simplified scenario.

假设我有以下表格,巧妙地以我自己的名字命名:

Let's say I have the following tables, cleverly named after myself:

'JohnsParentTable' (Id, Description) 
'JohnsChildTable' (Id, JohnsParentTableId, Description)

生成的类看起来像这样

public class JohnsParentTable
{
    public int Id { get; set; }
    public string Description { get; set; }
    public virtual ICollection<JohnsChildTable> JohnsChildTable { get; set; }

    public JohnsParentTable()
    {
        JohnsChildTable = new List<JohnsChildTable>();
    }
}

internal class JohnsParentTableConfiguration : EntityTypeConfiguration<JohnsParentTable>
{
    public JohnsParentTableConfiguration()
    {
        ToTable("dbo.JohnsParentTable");
        HasKey(x => x.Id);
        Property(x => x.Id).HasColumnName("Id").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(x => x.Description).HasColumnName("Description").IsRequired().HasMaxLength(50);
    }
}

public class JohnsChildTable
{
    public int Id { get; set; }
    public string Description { get; set; }
    public int JohnsParentTableId { get; set; }
    public JohnsParentTable JohnsParentTable { get; set; }
}

internal class JohnsChildTableConfiguration : EntityTypeConfiguration<JohnsChildTable>
{
    public JohnsChildTableConfiguration()
    {
        ToTable("dbo.JohnsChildTable");
        HasKey(x => x.Id);
        Property(x => x.Id).HasColumnName("Id").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(x => x.Description).HasColumnName("Description").IsRequired().HasMaxLength(50);
        HasRequired(a => a.JohnsParentTable).WithMany(c => c.JohnsChildTable).HasForeignKey(a => a.JohnsParentTableId);
    }
}

在数据库中,父表中有一行 ID 为 1,子表中有两行与该父表相关联.如果我这样做:

In the database I have a row in the parent table with an Id of 1 along with two rows in the child table tied to this parent. If I do this:

var parent = db.JohnsParentTable.FirstOrDefault(a => a.Id == 1)

对象已正​​确填充.但是,如果我尝试删除这一行:

The object is correctly populated. However, if I try to delete this row:

var parent = new Data.Models.JohnsParentTable() { Id = 1 };
db.JohnsParentTable.Attach(parent);
db.JohnsParentTable.Remove(parent);

db.SaveChanges();

实体框架尝试执行以下操作:

Entity framework tries to execute the following:

DELETE [dbo].[JohnsParentTable]
WHERE ([Id] = @0)
-- @0: '1' (Type = Int32)
-- Executing at 1/23/2014 10:34:01 AM -06:00
-- Failed in 103 ms with error: The DELETE statement conflicted with the REFERENCE constraint "FK_JohnsChildTable_JohnsParentTable". The conflict occurred in database "mydatabase", table "dbo.JohnsChildTable", column 'JohnsParentTableId'.
The statement has been terminated.

然后我的问题是我究竟缺少什么来确保实体框架知道它必须在删除父级之前删除JohnsChildTable"行?

My question then is what exactly am I missing to ensure Entity Framework knows that it must delete the 'JohnsChildTable' rows before deleting the parent?

推荐答案

这取决于你是想让 Entity Framework 删除孩子,还是让数据库来处理它.

It depends on whether you want Entity Framework to delete the children, or you want the database to take care of it.

如果您希望 EF 为所有子级生成删除语句并在删除父级之前执行这些语句,则必须先将所有子级加载到内存中.

If you want EF to generate a delete statement for all the children and execute those before deleting the parent, you have to load all the children into memory first.

因此,您不能简单地创建一个仅填充键的虚拟"实体,并期望删除子项.

So you can't simply create a "dummy" entity with just the key populated, and expect the children to be deleted.

为此,您必须让数据库处理删除.

For that to work, you have to let the database handle the deletion.

但是,子表上的外键必须启用级联删除.如果是这种情况,Entity Framework 只是为父级创建一个删除语句,数据库也知道删除子级.

The foreign key on the child table would have to have cascade deletes enabled however. If that's the case, Entity Framework just creates a delete statement for the parent, and the database knows to delete the children as well.

实体框架创建一个外键,默认情况下启用级联删除,如果需要关系,就像你的情况一样.(外键不能为空).

Entity Framework creates a foreign key with cascade deletes enabled by default, if the relationship is required, like in your case. (Foreign key can't be null).

如果您自己创建了数据库,则必须记住启用它.

If you have created the database yourself, you have to remember to enable it.

这篇关于实体框架 6:代码优先级联删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆