【发布时间】:2018-03-12 18:08:09
【问题描述】:
使用 C# MVC 和实体框架 v6.2.0
我有一个现有的模型,Caller
public class Caller
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required]
public string FirstName { get; set; }
}
我创建了一个新模型,LanguageChoice
public class LanguageChoice
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required]
public string Name { get; set; }
}
我想将这个新的LanguageChoice 添加到Caller
public class Caller
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required]
public string FirstName { get; set; }
public Guid LanguageChoice_Id { get; set; } // <----
[ForeignKey("LanguageChoice_Id")]
public LanguageChoice LanguageChoice { get; set; } // <----
}
我这样做是因为它将在我的 ViewModel 中成为 IEnumerable<SelectListItem>。
在我的数据库中,我已有 Caller 记录:
╔═════════════════════╦═══════════╗
║ Id ║ FirstName ║
╠═════════════════════╬═══════════╣
║ caller_guid_value_1 ║ Ryan ║
║ caller_guid_value_2 ║ John ║
╚═════════════════════╩═══════════╝
当我添加LanguageChoice 时,预期的结果将是:
╔═════════════════════╦═══════════╦═════════════════════════════╗
║ Id ║ FirstName ║ LanguageChoice_Id ║
╠═════════════════════╬═══════════╬═════════════════════════════╣
║ caller_guid_value_1 ║ Ryan ║ languageChoice_guid_value_1 ║
║ caller_guid_value_2 ║ John ║ languageChoice_guid_value_1 ║
╚═════════════════════╩═══════════╩═════════════════════════════╝
这是我的迁移:
public partial class AddCallerLanguageChoice : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.LanguageChoices",
c => new
{
Id = c.Guid(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 50),
})
.PrimaryKey(t => t.Id);
AddColumn("dbo.Callers", "LanguageChoice_Id", c => c.Guid(nullable: false));
CreateIndex("dbo.Callers", "LanguageChoice_Id");
AddForeignKey("dbo.Callers", "LanguageChoice_Id", "dbo.LanguageChoices", "Id", cascadeDelete: true);
}
public override void Down()
{
DropForeignKey("dbo.Callers", "LanguageChoice_Id", "dbo.LanguageChoices");
DropIndex("dbo.Callers", new[] { "LanguageChoice_Id" });
DropColumn("dbo.Callers", "LanguageChoice_Id");
DropTable("dbo.LanguageChoices");
}
}
这是我的错误:
ALTER TABLE 语句与 FOREIGN KEY 约束“FK_dbo.Callers_dbo.LanguageChoices_LanguageChoice_Id”冲突。冲突发生在数据库“aspnet-My Web App-20171030040324”、表“dbo.LanguageChoices”、“Id”列中。
有没有办法做到这一点,还是我应该继续允许LanguageChoice_Id 可以为空?
4年前的类似问题:Entity Framework The ALTER TABLE statement conflicted with the FOREIGN KEY constraint
- 4 岁,也许从那以后发生了一些变化
- 他们使用
int值作为 Id,我使用Guid,所以我无法提前猜测/假设 Id 值 - 我想避免创建一个迁移,其中
LanguageChoice_Id可以为空,然后是更新记录的种子方法,然后是另一个使LanguageChoice_Id不可为空的迁移,因为在将两个迁移都推送到 Azure 时会中断种子方法将最后运行。 (参见 Ari Roth 对 RicklsWright 回答的评论)
更新:
按照@henoc salinas'更新的答案,我来到了这个可行的迁移文件。
Henoc 的答案是公认的答案,这只是为了展示我最终得到的结果,不同之处在于我在此处插入了表值并使用非临时值更新了 Caller 的空值:
public override void Up()
{
CreateTable(
"dbo.LanguageChoices",
c => new
{
Id = c.Guid(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 50),
})
.PrimaryKey(t => t.Id);
Sql(String.Format("INSERT INTO LanguageChoices VALUES ('{0}','{1}')", Guid.NewGuid(), "English"));
Sql(String.Format("INSERT INTO LanguageChoices VALUES ('{0}','{1}')", Guid.NewGuid(), "Other"));
Sql(String.Format("INSERT INTO LanguageChoices VALUES ('{0}','{1}')", Guid.NewGuid(), "Spanish"));
AddColumn("dbo.Callers", "LanguageChoice_Id", c => c.Guid(nullable: true));
Sql("UPDATE Callers Set LanguageChoice_Id = (SELECT Id FROM LanguageChoices WHERE Name = \'English\') WHERE LanguageChoice_Id IS NULL");
AlterColumn("dbo.Callers", "LanguageChoice_Id", c => c.Guid(nullable: false));
CreateIndex("dbo.Callers", "LanguageChoice_Id");
AddForeignKey("dbo.Callers", "LanguageChoice_Id", "dbo.LanguageChoices", "Id", cascadeDelete: true);
}
public override void Down()
{
DropForeignKey("dbo.Callers", "LanguageChoice_Id", "dbo.LanguageChoices");
DropIndex("dbo.Callers", new[] { "LanguageChoice_Id" });
DropColumn("dbo.Callers", "LanguageChoice_Id");
DropTable("dbo.LanguageChoices");
}
}
【问题讨论】:
-
到目前为止一切都没有改变(很遗憾)。
-
@IvanStoev 真可惜。
标签: c# entity-framework tsql