实体框架迁移:仅在-Script输出中包含Go语句

Sta*_*man 17 entity-framework ef-migrations

作为规划实体框架迁移的一部分,为了调试数据移动,我经常使用-Script参数来生成脚本.

然后,我可以将此脚本带到查询分析器并将其包装在事务中,以便手动测试它.

我遇到了一个需要Go语句才能正确执行脚本的情况.以下代码已添加到迁移中,以便在适当的位置输出Go.

Sql("GO");
Run Code Online (Sandbox Code Playgroud)

当使用-Script时,这会在正确的位置添加GO语句.但是当没有使用-Script时.我得到例外......

System.Data.SqlClient.SqlException (0x80131904): Could not find stored procedure 'GO'.
Run Code Online (Sandbox Code Playgroud)

有没有一种安全的方法可以将Go命令添加到脚本中?

小智 15

我最近遇到了完全相同的情况.我的EF代码迁移通常会引入新的表或列,然后我还使用Sql(...)将数据迁移放入有时想要引用新表/列的迁移中.正如您所指出的,当作为EF代码迁移运行时,每个语句似乎都作为离散批处理发布到DB,因此没有任何问题.但是,为了满足生产部署限制,我们将一组代码迁移从sprint转换为单个脚本(使用-Script),以便为部署团队提供单个聚合SQL脚本迁移.正如您所指出的,此脚本文件有时会失败,因为它尝试从单个代码迁移中处理单个T SQL批处理,后面的语句尝试引用仅在批处理中先前定义的结构.

我并不特别喜欢我现在采取的两种方法来减轻这种情况,但在这里它们是:

一个.如果我当时正在考虑这个问题,我会将代码迁移分成两个迁移,这样当它们编写脚本时,它们会分成两个(或更多个)单独的批处理.我不喜欢这样,因为在代码迁移的开发过程中没有反馈这是必要的,因此它似乎容易出错.

湾 当我生成聚合脚本时,我会在临时数据库上运行它们来证明它们,并且我最终在该脚本中必要时手动注入"GO"语句.这是一个令人讨厌的过程,必须返回并执行,并导致-Script输出不是代码迁移的100%反映.

我没有花太多时间深入研究EF代码迁移的源代码,看看我是否能理解为什么它将"GO"解释为存储过程,以及源代码中是否有任何指向某种方式的方法提供一个避免这种情况的指令.


Ben*_*lor 8

internal sealed class Configuration : DbMigrationsConfiguration<Context>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        const string providerInvariantName = "System.Data.SqlClient";
        SetSqlGenerator(providerInvariantName, new BatchingMigrationSqlGenerator(GetSqlGenerator(providerInvariantName)));
    }

    protected override void Seed(Context context)
    {
    }

}

internal class BatchingMigrationSqlGenerator : MigrationSqlGenerator
{
    private readonly MigrationSqlGenerator migrationSqlGenerator;

    public BatchingMigrationSqlGenerator(MigrationSqlGenerator migrationSqlGenerator)
    {
        this.migrationSqlGenerator = migrationSqlGenerator;
    }

    public override IEnumerable<MigrationStatement> Generate(IEnumerable<MigrationOperation> migrationOperations, string providerManifestToken)
    {
        var migrationStatements = migrationSqlGenerator.Generate(migrationOperations, providerManifestToken).ToArray();
        foreach (var migrationStatement in migrationStatements)
        {
            migrationStatement.BatchTerminator = "GO";
        }
        return migrationStatements;
    }
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

2894 次

最近记录:

8 年,10 月 前