在实体优先迁移中为新Guid列添加默认值

时间:2016-03-22 15:39:20

标签: asp.net-mvc ef-code-first migration

我正在为我的项目使用实体代码首次迁移。我已经启动并运行了系统。但是,我需要添加一个新的Guid列,这是一个外键。在尝试更新数据库时,我收到以下错误:

  

ALTER TABLE语句与FOREIGN KEY约束冲突   " FK_dbo.Categories_dbo.aspnet_Roles_RoleId&#34 ;.冲突发生在   数据库" HelpDesk",table" dbo.aspnet_Roles",column' RoleId'。

所以我做了一些研究,发现Entity Framework 6 Code first Default value。但是,我无法弄清楚如何让它为Guid设置默认值。这是我试过的代码:

以下是迁移:

public override void Up()
{

     AddColumn("dbo.Categories", "RoleId", c => c.Guid(nullable: false, defaultValue: "4468ACB7-AD6F-471E-95CF-615115EA3A76"));
     CreateIndex("dbo.Categories", "RoleId");
     AddForeignKey("dbo.Categories", "RoleId", "dbo.aspnet_Roles", "RoleId");
}

public override void Down()
{
     DropForeignKey("dbo.Categories", "RoleId", "dbo.aspnet_Roles");
     DropIndex("dbo.Categories", new[] { "RoleId" });
     DropColumn("dbo.Categories", "RoleId");
}

如果我切换到此代码,我可以摆脱所有构建错误(但如果我运行Update-database,仍然会给我Alter Table错误:

AddColumn("dbo.Categories", "RoleId", c => c.Guid(nullable: false, identity: false, defaultValue: null));

如何将此转换为添加特定Guid作为默认值?

4 个答案:

答案 0 :(得分:1)

从错误中,我猜你从数据库中复制了这个Guid值"4468ACB7-AD6F-471E-95CF-615115EA3A76",并希望将它用于测试目的,EF注意到表中已存在的值并且正在抱怨。它也阻止你使用null,因为你告诉它阻止空值nullable: false。所以它期望你提供一个价值。您可以创建一个新的Guid并使用它。见下文

  AddColumn("dbo.Categories", "RoleId", c => c.Guid(nullable: false, defaultValue: Guid.NewGuid().ToString()));

答案 1 :(得分:0)

您的数据库初始化程序是否正在使用默认初始值设定项(CreateDatabaseIfNotExists)?改变这些可能有时会导致类似的问题。

这可能不是您的最终答案,但可能与问题有关。我已经附加了一篇关于数据库初始化程序的文章的链接,它可以帮助您找出问题所在。

http://www.codeguru.com/csharp/article.php/c19999/Understanding-Database-Initializers-in-Entity-Framework-Code-First.htm

据我所知,您的代码似乎不是问题的直接原因,它看起来更像是生成的迁移脚本导致问题。

答案 2 :(得分:0)

我想您已经知道了,但是我认为(未测试):

这应该适用于固定的C#-导值:

AddColumn("dbo.Categories", "RoleId", c => c.Guid(nullable: false, defaultValue: new Guid("4468ACB7-AD6F-471E-95CF-615115EA3A76")));

这对于使用defaultValueSql的固定C#字符串值应该有效:

AddColumn("dbo.Categories", "RoleId", c => c.Guid(nullable: false, defaultValueSql: "4468ACB7-AD6F-471E-95CF-615115EA3A76")));

对于其他(例如我)寻找随机(变化,唯一)值的人,您可能要使用defaultValueSql: "NewId()"(受this answer的启发):

 AddColumn("dbo.Categories", "RoleId", c => c.Guid(nullable: false, defaultValueSql: "NewId()")));

答案 3 :(得分:0)

使用实体框架迁移生成器:

在我第一次运行时,defaultValue 将 PK 设置为一个新的 Guid。使用 defaultValueSql: "NewId()" 完全符合我的目的。

protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropUniqueConstraint("PK_Payments", "Payments");

            migrationBuilder.DropColumn(
                name: "PaymentId",
                table: "Payments");

            migrationBuilder.AddColumn<Guid>(
                name: "PaymentId",
                table: "Payments",
                type: "uniqueidentifier",
                defaultValueSql: "NewId()",
                nullable: false);
}