我正在使用实体框架 - 代码优先,我遇到了一个问题,我必须禁用特定外键的级联删除。
这是我的实体类:
public class ChallengeMatch
{
public int Id { get; set; }
public int ChallengerClubMemberId { get; set; }
public int ChallengeeClubMemberId { get; set; }
public bool ChallengerWon { get; set; }
public string Score { get; set; }
public virtual ClubMember ChallengerClubMember { get; set; }
public virtual ClubMember ChallengeeClubMember { get; set; }
}
如果我允许Code First使用所有默认设置(包括级联删除)为该表生成数据库,则在尝试生成数据库对象时会抛出异常。
如果我将以下代码添加到DbContext
类,我不会再出现异常,但现在级联删除只会有点工作:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ChallengeMatch>()
.HasRequired(cm => cm.ChallengeeClubMember)
.WithMany()
.HasForeignKey(cm => cm.ChallengeeClubMemberId)
.WillCascadeOnDelete(false);
}
因此,我必须手工编写代码。具体来说,如果我要删除ClubMember 13,我必须删除ChallengeeClubMemberId为13的ChallengeMatch。
我不明白为什么任何这些都是必要的。为什么SQL Server不能处理级联删除,即使有两个外键指向同一个表?我想不出有什么理由会失败。
这应该是一个简单的三步过程(伪代码):
为什么SQL Server不能这样做或为什么不选择?
答案 0 :(得分:2)
问题是您的配置允许多个级联删除路径。如果您的属性都指向相同的ClubMember
,则会发生这种情况。 SQL Server不允许这样做。它更多地是关于SQL服务器的内部实现,更多细节可以在this answer中找到。我认为这个检查是简单而安全的解决方案,以避免在删除并行级联期间的某些竞争条件。