实体框架迁移自定义 SQL 不起作用

本文关键字:SQL 不起作用 自定义 迁移 框架 实体 | 更新日期: 2023-09-27 18:30:35

为什么这不起作用?

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 字段复制到代码字段。

编辑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]

当我在数据库上运行此输出作为完整脚本时,出现错误"列名'代码'无效"。但是每个语句都会像我预期的那样依次更新我的数据库。

这是否意味着我需要在多次迁移中执行这种风格的数据转置,或者有没有办法让迁移知道它必须分别执行迁移中的每个步骤?

实体框架迁移自定义 SQL 不起作用

尝试:

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

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

在迁移 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");
}

试试这个:

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