c# - 如何首先在 c# EF core 2.0 代码中强制迁移顺序
问题描述
我有两个表:“父母”和“孩子”:
public class Parent
{
public int Id { get; set; }
public string ExternalId { get; set; }
public string Description { get; set; }
}
public class Child
{
public int Id { get; set; }
public string ExternalId { get; set; }
public string Description { get; set; }
public string ParentExternalId { get; set; }
}
这将生成以下 SQL 脚本:
IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20171222072010_Initial')
BEGIN
CREATE TABLE [Parents] (
[Id] int NOT NULL IDENTITY,
[ExternalId] nvarchar(50) NOT NULL,
[Description] nvarchar(300) NULL,
CONSTRAINT [PK_Parents] PRIMARY KEY ([Id])
);
END;
IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20171222072010_Initial')
BEGIN
CREATE TABLE [Children] (
[Id] int NOT NULL IDENTITY,
[ExternalId] nvarchar(50) NOT NULL,
[Description] nvarchar(300) NULL,
[ParentExternalId] nvarchar(50) NOT NULL,
CONSTRAINT [PK_Children] PRIMARY KEY ([Id])
);
END;
现在我更改 Child 中的外键:
public class Child
{
public int Id { get; set; }
public string ExternalId { get; set; }
public string Description { get; set; }
#region foreign keys
public int ParentId { get; set; }
public Parent Parent { get; set; }
#endregion foreign keys
}
这会生成这个 SQL 脚本:
IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20180604085531_ChangeForeignKey')
BEGIN
DECLARE @var49 sysname;
SELECT @var49 = [d].[name]
FROM [sys].[default_constraints] [d]
INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
WHERE ([d].[parent_object_id] = OBJECT_ID(N'Children') AND [c].[name] = N'ParentExternalId');
IF @var49 IS NOT NULL EXEC(N'ALTER TABLE [Transactions] DROP CONSTRAINT [' + @var49 + '];');
ALTER TABLE [Children] DROP COLUMN [ParentExternalId];
END;
GO
IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20180604085531_ChangeForeignKey')
BEGIN
ALTER TABLE [Children] ADD [ParentId] int NOT NULL DEFAULT 0;
END;
GO
IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20180604085531_ChangeForeignKey')
BEGIN
ALTER TABLE [Children] ADD CONSTRAINT [FK_Children_Parents_ParentId] FOREIGN KEY ([ParentId]) REFERENCES [Parents] ([Id]) ON DELETE NO ACTION;
END;
GO
由于迁移中的顺序,我丢失了数据。我希望脚本首先添加新列“ParentId”,然后更新新列,然后删除列“ParentExternalId”。
有没有办法我可以强制这样做?
解决方案
我找到了。只需编辑 migration.cs 文件。它包含类似 migrationBuilder.AddColumn... 将其移至 migrationBuilder.DropColumn...
在两者之间您可以手动添加:
migrationBuilder.Sql(
@"
UPDATE c SET c.ParentId = p.Id
FROM Children AS c
INNER JOIN Parents AS p ON ...
WHERE c.ParentId <> p.Id
");
推荐阅读
- c++ - (C++)我在 OpenGL 中使用帧缓冲区是否走在正确的轨道上?
- python-3.x - 对于 Hermitian 矩阵,numpy.linalg.eig 给出的结果与 numpy.linalg.eigh 不同
- python - 无法使用硒单击按钮
- python - 如何返回python的中间输出并将其保存在生成过程中的数组中
- java - 消费者重启后正在重播来自主题的 Kafka 消息
- vb.net - 用于 RS232 应用程序中的 Threading.thread.sleep 的 VB.Net 替代方案
- r - 具有可选分组参数的用户函数,如果在 R 中使用管道
- reactjs - 在非 React 组件中访问 React persistStore
- java - 如何在 Android 的启动画面中添加旋转加载图标?
- c++ - c ++ gdb如何使用未使用的运算符*打印*shared_ptr