父删除时,EF将外键设置为null

时间:2014-12-09 08:37:13

标签: .net asp.net-mvc database entity-framework constraints

我有两个模型Team and Player

    public class Player
    {
            public int Id { get; set; }
    }

    public class FootballPlayer : Player
    {
        public int? TeamId { get; set; }

        public virtual FootballTeam Team { get; set; }
    }

    public class BasketballPlayer : Player
    {
        public int? TeamId { get; set; }

        public virtual BasketballTeam Team { get; set; }
    }

    public class BasketballTeam : Team
    {
        public int Id { get; set; }
        public virtual List<BasketballPlayer> Players { get; set; }
    }

public class FootballTeam : Team
    {
        public int Id { get; set; }
        public virtual List<FootballPlayer > Players { get; set; }
    }

这是一个配置

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Entity<FootballPlayer>().HasOptional(r => r.Team)
        .WithMany(a => a.Players)
        .HasForeignKey(b => new { b.TeamId })
        .WillCascadeOnDelete(false);

        modelBuilder.Entity<BasketballPlayer>().HasOptional(r => r.Team)
        .WithMany(a => a.Players)
        .HasForeignKey(b => new { b.TeamId })
        .WillCascadeOnDelete(false);

        base.OnModelCreating(modelBuilder);
    }

我使用的是EF Code First,我希望在删除团队时,不应该删除玩家,只有TeamId设置为null。如何做到这一点?

1 个答案:

答案 0 :(得分:1)

以下是我为您的实体定义的配置:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Player>().HasOptional(r => r.Team)
            .WithMany(a => a.Players)
            .HasForeignKey(b => new { b.TeamId })
            .WillCascadeOnDelete(false);

        base.OnModelCreating(modelBuilder);
    }

<强>更新

以上配置适用于您的原始实体,即简单的一对多关系(Team-&gt; Players)。新实体涉及继承,令人惊讶地消除了上述配置的影响。

对于新实体,配置仍然相同(HasOptional和CascadeOnDelete),但是,它不允许删除任何玩家正在使用的团队。它抛出

  

{“DELETE语句与REFERENCE约束冲突   \ “FK_dbo.FootballPlayers_dbo.FootballTeams_TeamId \”。冲突   发生在数据库\“EF6Testing.StudentContext \”,表中   \“dbo.FootballPlayers \”,列'TeamId'。\ r \ n声明已经   终止。“}

这是由于EF在一对多关系案例中添加的约束([FK_dbo.FootballPlayers_dbo.FootballTeams_TeamId])。但是,我不清楚的是,Team添加了相同的约束 - &gt;玩家案例和EF方便地没有“强制执行外键约束”。

那么为什么当实体具有继承层次结构时,EF不允许删除团队???

好的,让我们把这个谜团留给EF专家解决。

解决此问题的解决方案(可能的解决方案之一)是,您必须执行SQL脚本以删除并创建约束。该脚本将外键设置为可空。

我有兴趣找到上述问题的答案,以及EF(5或6或更高版本)中是否有更好的解决方案来处理这种情况。

USE [@DatabaseName]
GO

ALTER TABLE [dbo].[FootballPlayers] DROP CONSTRAINT [FK_dbo.FootballPlayers_dbo.FootballTeams_TeamId]
GO

ALTER TABLE [dbo].[FootballPlayers]  WITH CHECK ADD  CONSTRAINT [FK_dbo.FootballPlayers_dbo.FootballTeams_TeamId] FOREIGN KEY([TeamId])
REFERENCES [dbo].[FootballTeams] ([Id]) on delete set null
GO

ALTER TABLE [dbo].[FootballPlayers] CHECK CONSTRAINT [FK_dbo.FootballPlayers_dbo.FootballTeams_TeamId]
GO