DbSet启用了级联删除吗?

7

使用Entity Framework,在删除表中的任何记录之前,如何判断是否启用了删除级联?

public partial class DataContext : DbContext
{
    public DbSet<Building> Buildings { get; set; }
    public DbSet<Room>     Rooms     { get; set; }
}

DataContext context;
Building    building;

// Will this start a DELETE CASCADE, removing Rooms within the Building?
context.Buildings.Remove(building);

这是一个通用函数,因此我可以使用DbSet<T>或DbContext但不是T。
需要在运行时进行测试,就在调用Remove()之前。
您能否在执行删除操作之前检测到DELETE CASCADE呢?如果可以,该怎么做?

应该只通过Entity Framework吗?因为通过T-SQL很容易。 - Saeed Neamati
个人而言,我认为您不应该为任何表设置级联删除。在我看来,这是一个极其糟糕的想法,因为您可能会删除一条记录并锁定许多表,并删除数百万个相关记录,从而使系统停滞不前。此外,子记录的存在通常是父记录不应该被删除的关键。例如,您不应该删除过去有订单的客户。您可以考虑使用软删除方案。 - HLGEM
好的,假设记录必须被删除,我更喜欢自动完成这个过程(而不是手动删除,因为手动删除容易出现人为错误)。 - user1023602
2个回答

1
你可以很容易地使用一个T-SQL函数或查询来获取你想要的信息。尝试使用任何你想要的谓词将以下内容包装起来(例如,WHERE PK.TABLE_NAME = '我的表' AND C.DELETE_RULE = 'CASCADE')。如果存在记录,则你已经获得了所需的信息。
SELECT
    FK_TableName = FK.TABLE_SCHEMA + '.' + FK.TABLE_NAME,
    FK_ColumnName = CU.COLUMN_NAME,
    PK_TableName = PK.TABLE_SCHEMA + '.' + PK.TABLE_NAME,
    PK_ColumnName = PT.COLUMN_NAME,
    ConstraintName = C.CONSTRAINT_NAME,
    DeleteRule = C.DELETE_RULE
FROM
    INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK
    ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK
    ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU
    ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
INNER JOIN (
    SELECT
        i1.TABLE_NAME,
        i2.COLUMN_NAME
    FROM
        INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2
        ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
    WHERE
        i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
   ) PT ON PT.TABLE_NAME = PK.TABLE_NAME;

你可以将其包装成DbSet扩展,然后像这样调用它:context.Set<MyEntity>().UsesCascadeDelete(),这会使用你的谓词和其他任何想要的内容触发上述查询。
因为EF可以很容易地运行TSQL查询,所以我仍然认为它们是EF的一部分。

顺便提一下,上面的查询不是我写的,而是很久以前从别人那里拿来的。如果我找到这个人,我会给他们信用。此外,该查询对于我们进行集成测试非常有用...我们检查所有主键、外键约束,以确保数据库与我们期望的完全一致。 - BlackjacketMack
毫无疑问,我可以使用这样的查询,但问题是 - 如何? - user1023602

1

你觉得 '阅读FK元数据' 或 '检查实体的FK使用情况' 有帮助吗?似乎有几种尝试的方法,但我都没有尝试过。

通常我会在 映射文件 和代码库中手动检查这些信息。如果需要,也许之前的Stackoverflow答案可以帮助你创建更通用的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接