EF 4.1在具有两种关系的实体之间的两个方向上级联

时间:2012-03-28 21:37:08

标签: entity-framework entity-relationship

我有以下两个实体:

public class Tournament {
    public int TournamentID { get; set; }
    public String Name { get; set; }
    public int? OfficialID { get; set; }

    public virtual Official HeadOfficial { get; set; }

    public virtual ICollection<Official> Officials { get; set; }
}

public class Official {
    public int OfficialID { get; set; }
    public String Surname { get; set; }
    public String FirstName { get; set; }
    public int TournamentID { get; set; }

    public virtual Tournament Tournament { get; set; }
}

锦标赛可以有0..N官员和官方HAS来举办锦标赛。第二个关系是锦标赛可能有一个头衔。

为了使EF在制作数据库时正确解释这一点,我有以下内容:

    protected override void  OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<Tournament>()
            .HasOptional(t => t.HeadOfficial)
            .WithMany()
            .HasForeignKey(t => t.OfficialID);

        modelBuilder.Entity<Tournament>()
            .HasMany(t => t.Officials)
            .WithRequired(o => o.Tournament)
            .HasForeignKey(o => o.TournamentID);        
    }

如果我现在删除锦标赛,那么与该锦标赛相关联的所有官员都将被删除,这就是我想要的。但是,当我删除一个已经在其中一个比赛中成为官方官员的官方时,删除不会通过引用删除语句与Tournaments.OfficialID中的引用约束冲突。

1 个答案:

答案 0 :(得分:1)

  

如果我现在删除一个锦标赛,所有与之相关的官员   比赛被删除,这就是我想要的。但是,当我   删除一名官员已经成为其中一名官员   比赛,删除不通过引用删除   声明与参考约束冲突   Tournaments.OfficialID。

我认为这些情况完全不同。第一种情况是有效的,因为数据库中存在级联删除设置(EF确实在数据库中创建了此规则,因为该关系是必需的,这是默认行为)。

您的第二个关系是可选的,因此默认情况下没有级联删除。更重要的是:我不认为你想要级联删除,因为这意味着删除一名官员也会删除以此官员为首的比赛。

我只能想象,如果官方被删除,您希望将HeadOfficial引用设置为null。但是没有自动方式(比如级联删除)。您必须编写此类行为,例如:

using (var ctx = new MyContext())
{
    var officialToDelete = ctx.Officials.Single(o => o.OfficialID == 5);
    var tournaments = ctx.Tournaments.Where(t => t.OfficialID == 5).ToList();

    foreach (var tournament in tournaments)
        tournament.OfficialID = null;

    ctx.Officials.Remove(officialToDelete);

    ctx.SaveChanges();
}

我认为foreach循环不是必需的,因为EF会在您调用null时修复关系(=将外键设置为Remove)。 (基本上EF本身在内部执行此循环。)但是将锦标赛加载到上下文中非常重要,因为EF关心此关系修复(仅适用于附加(=已加载)实体),而不是数据库(与级联删除相反) )。