Как навести порядок в миграциях в коде c # EF core 2.0 - PullRequest
0 голосов
/ 12 июня 2018

У меня есть две таблицы: «Родители» и «Дети»:

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 голосов
/ 12 июля 2019

Я нашел это.Просто отредактируйте файлigration.cs.Он содержит что-то вродеigrationBuilder.AddColumn ... Переместите его перед миграциейBuilder.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
");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...