添加新的外键 table 自动迁移 entity framework mvc c#
Adding foreign key with new table with automatic migrations entity framework mvc c#
我想在 SQL 服务器中添加一个新的 table 和一个现有 table 的外键,并使用代码优先自动迁移。我遇到的唯一问题是 table 中有数据,我无法将外键设置为现有数据的默认值。
例子:
汽车table
名称颜色
矩阵蓝色
凯美瑞红色
现在我想添加品牌 table :
汽车table
Id姓名颜色BrandId
1矩阵蓝色1
2凯美瑞红1
品牌table
Id姓名
1丰田
问题是:当我运行 Update-Database 命令时,如何在我的 Model Car 中将默认 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'.
现在,在我的 Configuration.cs 文件中,我这样添加我的汽车品牌:
context.Brands.AddOrUpdate(
new Brand{ Id = 1, Name = "Toyota" }
);
在我的上下文中,我重写了 protected override void OnModelCreating (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;
}
"Automatic migration" 在 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; }
、 运行 您的项目,您将不会再收到任何错误。
也许这不是这个问题的最佳解决方案,但如果您的外键有一些主键,则可以使用这种方式。
我想在 SQL 服务器中添加一个新的 table 和一个现有 table 的外键,并使用代码优先自动迁移。我遇到的唯一问题是 table 中有数据,我无法将外键设置为现有数据的默认值。
例子:
汽车table
名称颜色
矩阵蓝色
凯美瑞红色
现在我想添加品牌 table :
汽车table
Id姓名颜色BrandId
1矩阵蓝色1
2凯美瑞红1
品牌table
Id姓名
1丰田
问题是:当我运行 Update-Database 命令时,如何在我的 Model Car 中将默认 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'.
现在,在我的 Configuration.cs 文件中,我这样添加我的汽车品牌:
context.Brands.AddOrUpdate(
new Brand{ Id = 1, Name = "Toyota" }
);
在我的上下文中,我重写了 protected override void OnModelCreating (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;
}
"Automatic migration" 在 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; }
、 运行 您的项目,您将不会再收到任何错误。
也许这不是这个问题的最佳解决方案,但如果您的外键有一些主键,则可以使用这种方式。