使用自动迁移实体框架 mvc c# 的新表添加外键



我想在 SQL Server 中添加一个新表和一个现有表的外键,代码优先自动迁移。我唯一的问题是表中有数据,我无法将外键设置为现有数据的默认值。

示例 :

汽车表

名称 颜色
矩阵
凯美瑞

现在我想添加品牌表:

汽车表

ID

名称颜色品牌 ID
1 矩阵1
2凯美瑞1

品牌表

身份证名称
1丰田

问题是:当我运行更新数据库命令时,如何在我的模型车中将默认 BrandId 设置为 1,而不会出现外键约束错误?

The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_dbo.Cars_dbo.Brands_BrandId". The conflict occurred in database "Example", table "dbo.Brands", column 'Id'.

现在,在我的配置.cs文件中,我像这样添加我的汽车品牌:

context.Brands.AddOrUpdate(
                new Brand{ Id = 1, Name = "Toyota" }
           );

在我的上下文中,我覆盖了受保护的覆盖 void OnModelCreate( DbModelBuilder modelBuilder ) 并应用此关系:

modelBuilder.Entity<Car>().HasRequired<Brand>(t => t.Brand);

在我的汽车模型中:

[Required( ErrorMessage = "The brand is mandatory" )]
public int BrandId { get; set; }
[ForeignKey( "BrandId" )]
public virtual Brand Brand { get; set; }

在 Car 模型的构造函数中,我将默认值设置为 BrandId:

public Car() 
{
    BrandId = 1;
}
EF

中的"自动迁移"是一个有点模棱两可的术语,但如果您指的是尝试为您修改数据库的术语,则不能。您必须使用从 Visual Studio 控制台运行Add-Migration的迁移**形式来生成迁移类。无论如何,这通常是处理迁移的更好方法。

为此,我通常会使用 Sql 函数来禁用约束检查。

Sql("ALTER TABLE Cars NOCHECK CONSTRAINT ALL")

添加 FK,执行一些逻辑来填充该列,然后再次启用约束检查。

Sql("ALTER TABLE Cars CHECK CONSTRAINT ALL")

另一种可能性是,也许系统中已经有汽车,你想要拥有null品牌,但任何未来的汽车都必须参考现有的品牌。在这种情况下,您可以在该列中允许NULL,并在代码中处理验证要求。

事实上,您应该始终处理代码中的所有验证,永远不要依赖数据库为您进行验证。


** 这些有时仍称为自动迁移,因为通常将它们设置为在应用程序运行时自动应用。

我也有这个问题,我找到了解决这个问题的方法。

首先,您应该只定义public int BrandId { get; set; }并使用它运行您的项目。然后,在数据库中为 BrandId 提供一个有效值(外键的主键)。现在,您可以定义public virtual Brand Brand { get; set; },再次运行您的项目,您将不会再收到任何错误。

也许这不是这个问题的最佳解决方案,但是如果你有一些外键的主键,你可以使用这种方式。

最新更新