实体框架迁移自定义SQL无法正常工作

时间:2016-01-14 16:30:29

标签: c# entity-framework ef-migrations

为什么这不起作用?

AddColumn("dbo.Bins", "Code", c => c.String());
//custom copy data from old BinCode column
Sql("UPDATE Bins SET Code = BinCode WHERE BinCode IS NOT NULL");
DropColumn("dbo.Bins", "BinCode");

Bins的Bin.BinCode设置了值,当我在DbMigration内运行时,我发现Bin.Code是NULL

编辑: 我实际上并没有在包管理器控制台中运行Update-Database,但是我从我的工作单元源执行:

        Database.SetInitializer<eVendContext>(new MigrateDatabaseToLatestVersion<eVendContext, Configuration>());

编辑2: 只是为了澄清,数据库 成功更新到最新的迁移。简单的说,完成后,数据不会从BinCode字段复制到Code字段。

编辑3: 以下是Update-database -verbose的相关输出:

ALTER TABLE [dbo].[Bins] ADD [Code] [nvarchar](max)
UPDATE Bins SET Bins.Code = BinCode WHERE BinCode IS NOT NULL
DECLARE @var0 nvarchar(128)
SELECT @var0 = name
FROM sys.default_constraints
WHERE parent_object_id = object_id(N'dbo.Bins')
AND col_name(parent_object_id, parent_column_id) = 'BinCode';
IF @var0 IS NOT NULL
    EXECUTE('ALTER TABLE [dbo].[Bins] DROP CONSTRAINT [' + @var0 + ']')
ALTER TABLE [dbo].[Bins] DROP COLUMN [BinCode]

当我从我的数据库上的verbose运行此输出作为完整脚本时,我收到错误“无效的列名'代码'”。但是每个语句反过来都会像我期望的那样更新我的数据库。

这是否意味着我需要在多次迁移中执行此类型的数据转置,或者是否有办法让迁移知道它必须单独执行迁移中的每个步骤?

3 个答案:

答案 0 :(得分:3)

尝试:

Sql("UPDATE Bins SET Code = BinCode WHERE BinCode IS NOT NULL", true);

我怀疑该语句可能是在删除Code列之后或创建之前执行的。这可以确保它在用于迁移的事务之外执行。

答案 1 :(得分:1)

在您的迁移Seed()中尝试这样的操作,这将在添加列后运行:

if (context.Bins.Any(b => b.Code == null && b.BinCode != null)
{
    context.Database.ExecuteSQLCommand("UPDATE Bins SET Code = BinCode WHERE BinCode IS NOT NULL");
}

答案 2 :(得分:0)

试试这个:

Sql("UPDATE Bins SET Bins.Code = Bins.BinCode WHERE Bins.BinCode IS NOT NULL");