我有一个.NET Core Web应用程序,其后端具有EF Core(代码优先)数据库。我需要在初始化时立即将一堆数据播种到数据库中,因为该项目仍在开发中。
但是我无法摆脱这些FOREIGN KEY SQL异常!它们就像一个漏水的管道,每当我进行更改以修复它时,都会弹出另一个。而且这些模型之间的联系是如此之多,以至于泄漏很多。我需要一劳永逸地修复它们。
我已经定义了所有模型和模型关系,正在使用Bogus库进行C#生成数据,编写了所有代码来创建虚假实体并将它们按照应有的方式捆绑在一起。 / p>
我无法发布确切的代码,因为它是专有的(我是承包商),但是我可以提供它的摘要:
// Generation of entities
var apples = GenerateBogusApples(5);
var bananas = GenerateBogusBananas(20);
// Add them to context
context.Apples.AddRange(apples);
context.SaveChanges();
context.Bananas.AddRange(bananas);
context.SaveChanges();
// Set up relationships
foreach (Bananas b in bananas)
{
b.Apple = apples.Random(); // little pseudocode, hope you don't mind
}
// One final
context.SaveChanges();
// End result: A banana with an apple object associated with it
// My actual task is way more complicated, with lots of interdependency :/
我只需要数据库处于一种状态,即根据业务逻辑,我插入到其中的所有虚拟数据都将与相关数据正确关联。相反,我遇到了许多种不同的外键错误,例如“ MERGE语句与FOREIGN KEY约束冲突”。
答案 0 :(得分:1)
您可以使用以下两个步骤来禁用(NOCHECK)所有外键,并在加载后重新启用它们:
create or alter procedure DisableAllConstraints
as
begin
DECLARE @sql nvarchar(max);
DECLARE c CURSOR local read_only FOR
SELECT 'ALTER TABLE '+ quotename(schema_name(t.schema_id)) + '.' + quotename(name) + ' NOCHECK CONSTRAINT ALL;'
FROM sys.tables t
where t.is_ms_shipped = 0
and t.name <> 'sysdiagrams';
OPEN c;
FETCH NEXT FROM c INTO @sql;
WHILE @@FETCH_STATUS = 0
BEGIN
print @sql;
exec (@sql);
FETCH NEXT FROM c INTO @sql;
END
close c;
deallocate c;
end
go
create or alter procedure EnableAllConstraints
as
begin
DECLARE @sql nvarchar(max);
DECLARE c CURSOR local read_only FOR
--use "with check check constraint all" to validate existing data _and_ enforce the constraint for new DML
--use "check constraint all" to enforce the constraint but not check the existing data
SELECT 'alter table '+ quotename(schema_name(t.schema_id)) + '.' + quotename(name) + ' with check check constraint all;'
--SELECT 'alter table '+ quotename(schema_name(t.schema_id)) + '.' + quotename(name) + ' check constraint all;'
FROM sys.tables t
where t.is_ms_shipped = 0
and t.name <> 'sysdiagrams';
OPEN c;
FETCH NEXT FROM c INTO @sql;
WHILE @@FETCH_STATUS = 0
BEGIN
print @sql;
exec (@sql);
FETCH NEXT FROM c INTO @sql;
END
close c;
deallocate c;
end