首页 > 解决方案 > 实体框架迁移 - Alter Table 语句与外键约束冲突

问题描述

我正在使用 EF 代码优先迁移使用 C#/.NET 4.5 框架创建各种博客。

事情一直进展顺利,直到在我的主要课程中添加了第三个关系。

我有一个“故事”类(有点像博客的“帖子”),其中作者作为登录的用户(在控制器中设置)、标题、一些内容、创建日期和一种类型和类型的故事。

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

        public string AuthorId { get; set; }
        public virtual ApplicationUser Author { get; set; }

        [Required]
        [StringLength(50)]
        public string Title { get; set; }

        [Required]
        [MinLength(100), MaxLength(5000)]
        public string Content { get; set; }

        [Required]
        public int GenreId { get; set; }
        public Genre Genre { get; set; }

        [Required]
        public int StoryTypeId { get; set; }
        public StoryType StoryType { get; set; }

        public DateTime CreatedAt { get; set; }
    }

我将故事类型作为属性添加到故事中。StoryType 链接到 StoryType 模型:

public class StoryType
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

我确保将我的数据库集添加到我的应用程序数据库上下文中:

public DbSet<Genre> Genres { get; set; }
public DbSet<Story> Stories { get; set; }
public DbSet<StoryType> StoryTypes { get; set; }

我几乎遵循了我用来创建故事和类型之间关系的相同步骤(效果很好)。在开始构建 StoryType 控制器之前,我进入 package-console 并运行:

add-migration

返回:

 public partial class CreateTypeTable : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.StoryTypes",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        Name = c.String(),
                    })
                .PrimaryKey(t => t.Id);

            AddColumn("dbo.Stories", "StoryTypeId", c => c.Int(nullable: false));
            CreateIndex("dbo.Stories", "StoryTypeId");
            AddForeignKey("dbo.Stories", "StoryTypeId", "dbo.StoryTypes", "Id", cascadeDelete: true);
        }

        public override void Down()
        {
            DropForeignKey("dbo.Stories", "StoryTypeId", "dbo.StoryTypes");
            DropIndex("dbo.Stories", new[] { "StoryTypeId" });
            DropColumn("dbo.Stories", "StoryTypeId");
            DropTable("dbo.StoryTypes");
        }
    }

扫了一眼,没发现问题,然后跑:

update-database

在包控制台中。

哪个返回:

Error Number:547,State:0,Class:16
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_dbo.Stories_dbo.StoryTypes_StoryTypeId". The conflict occurred in database "aspnet-HiRatik.Stories-20180724043630", table "dbo.StoryTypes", column 'Id'.

我不确定这里出了什么问题。我对流派关系做了同样的过程,它奏效了。我没看出两者有什么不同。

标签: c#mysqlasp.net-mvcentity-framework

解决方案


因为 Story 类中的 StoryTypeId 不接受 null 所以你需要使 StoryTypeId 可以为空:

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

        public string AuthorId { get; set; }
        public virtual ApplicationUser Author { get; set; }

        [Required]
        [StringLength(50)]
        public string Title { get; set; }

        [Required]
        [MinLength(100), MaxLength(5000)]
        public string Content { get; set; }

        [Required]
        public int GenreId { get; set; }
        public Genre Genre { get; set; }

        public int? StoryTypeId { get; set; }
        public StoryType StoryType { get; set; }

        public DateTime CreatedAt { get; set; }
    }

或者您首先创建表 StoryType 并向其中添加元素,然后添加具有默认值的 StoryTypeId:

公共类故事 { 公共 int Id { 获取;放; }

    public string AuthorId { get; set; }
    public virtual ApplicationUser Author { get; set; }

    [Required]
    [StringLength(50)]
    public string Title { get; set; }

    [Required]
    [MinLength(100), MaxLength(5000)]
    public string Content { get; set; }

    [Required]
    public int GenreId { get; set; }
    public Genre Genre { get; set; }

    [[DefaultValue(1)]]
    public int StoryTypeId { get; set; }
    public StoryType StoryType { get; set; }

    public DateTime CreatedAt { get; set; }
}

在这种情况下,您必须在创建 StoryType 以及将 StoryTypeId 添加到 Story 类之后更新数据库


推荐阅读