EF 6.0 миграции: ContextKey в MigrationHistory имеет значение null

я обновился до EF6, и это не было весело. Я создал новую миграцию, которая просто меняет два поля на значение null.

public partial class AllowNullableFieldsForImage : DbMigration
{
    public override void Up()
    {
        AlterColumn("dbo.Scabs", "image_height", c => c.Int());
        AlterColumn("dbo.Scabs", "image_width", c => c.Int());
    }

    public override void Down()
    {
        AlterColumn("dbo.Scabs", "image_width", c => c.Int(nullable: false));
        AlterColumn("dbo.Scabs", "image_height", c => c.Int(nullable: false));
    }
}

когда я запускаю update-database Я получаю следующую ошибку:

не удается вставить значение NULL в столбец "ContextKey", таблица " ScabsContext.dbo.__MigrationHistory'; столбец не допускает значения null. Ошибка вставки. Заявление было прекращено.

Я нашел несколько статей, в которых упоминается новый Поле ContextKey в MigrationHistory, но ничего, что отвечает на мои вопросы... Почему это поле null? Есть ли способ (и мне нужно) указать значение для ContextKey? Я думал, это делается автоматически?

2 ответов


мне кажется, что вы, возможно, использовали базу данных для тестирования ваших миграций, когда вы вносили изменения. Таблица хронологии миграции EF5 имеет следующую структуру:

CREATE TABLE [dbo].[__MigrationHistory](
    [MigrationId] [nvarchar](255) NOT NULL,
    [Model] [varbinary](max) NOT NULL,
    [ProductVersion] [nvarchar](32) NOT NULL
    CONSTRAINT [PK_dbo.__MigrationHistory] PRIMARY KEY CLUSTERED 
    ( [MigrationId] ASC )
)

когда я обновил проект с EF5 на EF6, я добавил явную миграцию для этой цели. Если вы используете десятичные поля, миграция будет необходима в любом случае, так как она воссоздает их, используя явную точность. Когда вы запускаете эту первую миграцию под EF6, она воссоздает таблицу истории миграции с помощью новой структуры, которая выглядит следующим образом...

CREATE TABLE [dbo].[__MigrationHistory2] (
    [MigrationId] [nvarchar](150) NOT NULL,
    [ContextKey] [nvarchar](300) NOT NULL,
    [Model] [varbinary](max) NOT NULL,
    [ProductVersion] [nvarchar](32) NOT NULL,
    CONSTRAINT [PK_dbo.__MigrationHistory2] PRIMARY KEY ([MigrationId], [ContextKey])
)

вы можете видеть, что эта таблица включает поле ContextKey, которое не является нулевым. Из-за ошибки, которую вы получаете, я бы предположил, что вы пытаетесь запустить миграцию с помощью EF5 в базе данных EF6-format.

Если вы хотите вернуть свою базу данных в формат EF5 для запуска миграции из EF5, просто удалите поле ContextKey и воссоздайте первичный ключ:

ALTER TABLE dbo.__MigrationHistory DROP CONSTRAINT [PK_dbo.__MigrationHistory2]
ALTER TABLE dbo.__MigrationHistory DROP COLUMN ContextKey
ALTER TABLE dbo.__MigrationHistory ADD CONSTRAINT [PK_dbo.__MigrationHistory] PRIMARY KEY (MigrationId)

Я создал следующий скрипт для обновления истории миграции ef5 до ef6. Возможно, вы захотите изменить Migrations.Configuration чтобы ваше пространство имен соответствовало вашему.

BEGIN TRANSACTION

SELECT *
INTO [tmp__MigrationHistory]
FROM [__MigrationHistory]

SELECT *
FROM [tmp__MigrationHistory]

DROP TABLE [__MigrationHistory]

CREATE TABLE [dbo].[__MigrationHistory] (
    [MigrationId] [nvarchar](150) NOT NULL
    ,[ContextKey] [nvarchar](300) NOT NULL
    ,[Model] [varbinary](max) NOT NULL
    ,[ProductVersion] [nvarchar](32) NOT NULL
    ,CONSTRAINT [PK_dbo.__MigrationHistory] PRIMARY KEY CLUSTERED (
        [MigrationId] ASC
        ,[ContextKey] ASC
        ) WITH (
        PAD_INDEX = OFF
        ,STATISTICS_NORECOMPUTE = OFF
        ,IGNORE_DUP_KEY = OFF
        ,ALLOW_ROW_LOCKS = ON
        ,ALLOW_PAGE_LOCKS = ON
        )
    ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

INSERT INTO [__MigrationHistory] (
    [MigrationId]
    ,[ContextKey]
    ,[Model]
    ,[ProductVersion]
    )
SELECT [MigrationId]
    ,'Migrations.Configuration'
    ,[Model]
    ,[ProductVersion]
FROM [tmp__MigrationHistory]

SELECT *
FROM [__MigrationHistory]

DROP TABLE [tmp__MigrationHistory]

ROLLBACK TRANSACTION