如何在c#EF core 2.0代码中强制执行迁移订单

时间:2018-06-12 09:12:11

标签: c# entity-framework entity-framework-core

我有两张桌子:“父母”和“孩子”:

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”。

有没有办法可以强迫这个?

1 个答案:

答案 0 :(得分:0)

我找到了。只需编辑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
");