【问题标题】:Adding Default Value for New Guid Column in Entity First Migration在实体优先迁移中为新的 Guid 列添加默认值
【发布时间】:2016-03-22 15:39:20
【问题描述】:

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

ALTER TABLE 语句与 FOREIGN KEY 约束冲突 “FK_dbo.Categories_dbo.aspnet_Roles_RoleId”。冲突发生在 数据库“HelpDesk”,表“dbo.aspnet_Roles”,列“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 作为默认值?

【问题讨论】:

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


    【解决方案1】:

    我想你已经弄清楚了,但我认为(未经测试):

    • 这应该适用于 constant(固定)C#-Guid-value:

      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")));
      
    • 对于寻找由 SqlServer 确定的 可变唯一 值(每个表行不同)的其他人(如我),您可能需要使用 defaultValueSql: "NewId()" (灵感来自this answer):

       AddColumn("dbo.Categories", "RoleId", c => c.Guid(nullable: false, defaultValueSql: "NewId()")));
      
    • 编辑:未经测试,但也可能是可变独特顺序值(不同的每个表行),由 SqlServer 确定,使用 defaultValueSql: "newsequentialid()"(灵感来自 this answer):

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

      但请注意,SqlServer 会增加/排序序列different from C#

    【讨论】:

      【解决方案2】:

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

      我第一次运行时,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);
      }
      

      【讨论】:

      • 这个解决方案对我有用。我不得不使用 defaultValueSql 而不是 defaultValue,因为列类型是“唯一标识符”。谢谢。
      【解决方案3】:

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

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

      【讨论】:

      • 我不需要创建新的 Guid。我需要使用该值。新字段是外键,是另一个表中要设置为默认值的值。
      【解决方案4】:

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

      这可能不是您的最终答案,但可能与问题有关。我附上了一篇关于数据库初始化器的不错文章的链接,它可以帮助您隔离问题。

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

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

      【讨论】:

      • Pedro Aren't Guids 默认情况下是不可为空的,因为它们的存在记录已经在数据库中 - 通过添加不可为空的记录不会产生此错误吗?因为表中已经存在的所有记录都不符合这个要求?
      猜你喜欢
      • 1970-01-01
      • 2016-05-14
      • 2011-10-29
      • 2015-09-10
      • 2019-12-31
      • 1970-01-01
      • 1970-01-01
      • 2015-03-19
      • 2013-04-05
      相关资源
      最近更新 更多