Asp.net mvc 实体框架代码优先迁移NOCHECK约束?
在具有nocheck约束的代码优先迁移中,是否可以更改表?除了通过Asp.net mvc 实体框架代码优先迁移NOCHECK约束?,asp.net-mvc,entity-framework,entity-framework-migrations,Asp.net Mvc,Entity Framework,Entity Framework Migrations,在具有nocheck约束的代码优先迁移中,是否可以更改表?除了通过updatedatabase-script获取SQL脚本并修改SQL语句之外,我还没有找到任何方法来实现这一点。您可以尝试创建自己的MigrationSqlGenerator并将其用于迁移(您可以在DbMigrationsConfiguration中设置自定义SQL生成器)-我认为在添加外键=覆盖生成(AddForeignKeyIperation操作)后,继承SqlServerMigrationSqlGenerator并添加NOC
updatedatabase-script
获取SQL脚本并修改SQL语句之外,我还没有找到任何方法来实现这一点。您可以尝试创建自己的MigrationSqlGenerator
并将其用于迁移(您可以在DbMigrationsConfiguration
中设置自定义SQL生成器)-我认为在添加外键=覆盖生成(AddForeignKeyIperation操作)
后,继承SqlServerMigrationSqlGenerator
并添加NOCHECK
就足够了
无论如何,使用EF的NOCHECK是一种灾难。如果希望数据库没有选中的约束,请不要使用EF,因为每次达到不一致时它都会崩溃 您可以尝试创建自己的
MigrationSqlGenerator
并将其用于迁移(您可以在DbMigrationsConfiguration
中设置自定义SQL生成器)-我认为在添加外键=覆盖Generate>后继承SqlServerMigrationSqlGenerator
并添加NOCHECK
(AddForeignKeyIperation操作)
无论如何,对EF使用
NOCHECK
是一种灾难。如果希望数据库没有选中的约束,请不要使用EF,因为每次出现不一致时它都会崩溃。另一种一次性的方法是调用SQL手动创建FK,就像这样,从Up()方法中调用:
// AddForeignKey("dbo.EFElementGroupEntries", "ConstraintCode", "dbo.EFElementConstraints", "Code");
Sql(@"ALTER TABLE [dbo].[EFElementGroupEntries] WITH NOCHECK
ADD CONSTRAINT[FK_dbo.EFElementGroupEntries_dbo.EFElementConstraints_ConstraintCode] FOREIGN KEY([ConstraintCode])
REFERENCES[dbo].[EFElementConstraints]([Code])");
Sql(@"ALTER TABLE [dbo].[EFElementGroupEntries] CHECK CONSTRAINT [FK_dbo.EFElementGroupEntries_dbo.EFElementConstraints_ConstraintCode]");
对于一次性情况,另一种方法是从Up()
方法中调用SQL手动创建FK,就像这样:
// AddForeignKey("dbo.EFElementGroupEntries", "ConstraintCode", "dbo.EFElementConstraints", "Code");
Sql(@"ALTER TABLE [dbo].[EFElementGroupEntries] WITH NOCHECK
ADD CONSTRAINT[FK_dbo.EFElementGroupEntries_dbo.EFElementConstraints_ConstraintCode] FOREIGN KEY([ConstraintCode])
REFERENCES[dbo].[EFElementConstraints]([Code])");
Sql(@"ALTER TABLE [dbo].[EFElementGroupEntries] CHECK CONSTRAINT [FK_dbo.EFElementGroupEntries_dbo.EFElementConstraints_ConstraintCode]");
如果目标是创建所需的外键,但更新数据库由于现有数据而失败,则只需分两个阶段进行。例如,假设我想在1:m关系的玩家类中为团队添加外键,其中所有玩家都必须分配给一个团队。假设所有类都有整数标识主键。。。
1.向播放器添加两个常用属性,但外键使用可为空的int。即:
public int? TeamID { get; set; }
public virtual Team Team { get; set; }
添加迁移并更新数据库。所有TeamID值都将为null,但允许您创建关系
接下来,修复您的数据,以便为每个玩家分配一个有效的TeamID。如果您正在播种玩家数据,您还需要在那里提供TeamID值
修改PLAYER类,使int不再为null:
public int TeamID{get;set;}
添加另一个迁移并再次更新数据库。您应该可以开始了
如果目标是创建所需的外键,但更新数据库由于现有数据而失败,则只需分两个阶段进行。例如,假设我想在1:m关系的玩家类中为团队添加外键,其中所有玩家都必须分配给一个团队。假设所有类都有整数标识主键。。。
1.向播放器添加两个常用属性,但外键使用可为空的int。即:
public int? TeamID { get; set; }
public virtual Team Team { get; set; }
添加迁移并更新数据库。所有TeamID值都将为null,但允许您创建关系
接下来,修复您的数据,以便为每个玩家分配一个有效的TeamID。如果您正在播种玩家数据,您还需要在那里提供TeamID值
修改PLAYER类,使int不再为null:
public int TeamID{get;set;}
添加另一个迁移并再次更新数据库。您应该可以开始了
谢谢你的回答。我非常清楚使用NOCHECK的风险,相关的更改非常小,我相信NOCHECK是我的唯一选择。我将查看MigrationSqlGenerator。谢谢你的回答。我非常清楚使用NOCHECK的风险,相关的更改非常小,我相信NOCHECK是唯一的选择我的情况。我将查看MigrationSqlGenerator。这个答案对我来说似乎是最好的,但它有任何缺点或风险?这个答案对我来说似乎是最好的,但它有任何缺点或风险?我必须使用migrationBuilder.Sql(),而不仅仅是Sql(),以防其他人想知道它的定义在哪里而不是Sql()我必须使用migrationBuilder.Sql(),以防其他人想知道这是从哪里定义的