EF 6.0迁移:MigrationHistory中的ContextKey为null

时间:2013-12-19 15:06:30

标签: c# entity-framework ef-code-first ef-migrations

我已经更新到EF6并且它并不好玩。我创建了一个新的迁移,只是将两个字段更改为可空。

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';列不允许空值。 INSERT失败。   声明已经终止。

我发现一些文章提到了MigrationHistory中的新ContextKey字段,但没有任何内容可以回答我的问题......为什么这个字段为空?有没有办法(我是否需要)为ContextKey指定一个值?我以为这是自动完成的?

2 个答案:

答案 0 :(得分:14)

在我看来,您在进行更改时可能一直在使用数据库来测试迁移。 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字段。由于您遇到的错误,我建议您尝试在EF6格式的数据库上使用EF5运行迁移。

如果要将数据库恢复为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)

答案 1 :(得分:5)

我创建了以下脚本来将ef5 MigrationHistory更新为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