如何将EF6迁移定位到仅在SQL Server上执行?

时间:2015-11-20 16:39:51

标签: sql-server entity-framework-6 ef-migrations sql-server-ce-4

我想确保在SQL Server中启用了特定功能。我目前正在使用EF6迁移来生成我的更改脚本。我正在使用针对SQL Server 2012和SQL Server CE 4的迁移(用于映射的基本单元测试)。 SQL Server CE不支持我要启用的特定功能。

如何创建仅适用于SQL Server的迁移?

以下是有问题的迁移:

public partial class EnableSnapshotIsolation : DbMigration
{
    public override void Up()
    { 

        Sql(@"  ALTER DATABASE CURRENT
                SET READ_COMMITTED_SNAPSHOT ON", true);

        Sql(@"  ALTER DATABASE CURRENT
                SET ALLOW_SNAPSHOT_ISOLATION ON", true);
    }


    public override void Down()
    {
        Sql(@"  ALTER DATABASE CURRENT
                SET READ_COMMITTED_SNAPSHOT OFF", true);

        Sql(@"  ALTER DATABASE CURRENT
                SET ALLOW_SNAPSHOT_ISOLATION OFF", true);
    }
}

注意:我们手动部署更改脚本。一个人打开SSMS窗口并执行脚本。我使用update-database -script命令提供了一个更改脚本,作为构建打包过程的一部分。因此EF不会创建数据库。

1 个答案:

答案 0 :(得分:0)

在讨论了很多之后,我发现在迁移过程中没有办法根据数据库类型来抑制迁移。但是,您可以实现自己的migrator for a specific provider

我的解决方案涉及更新我的配置类。

public class Configuration : DbMigrationsConfiguration<ApplicationDbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        MigrationsDirectory = "Data\\Migrations";
        SetSqlGenerator("System.Data.SqlClient", new SqlMigrator());
    }

    private class SqlMigrator : SqlServerMigrationSqlGenerator
    {
        public override IEnumerable<MigrationStatement> Generate(
            IEnumerable<MigrationOperation> migrationOperations, string providerManifestToken)
        {
            var statements = new List<MigrationStatement>
            {
                new MigrationStatement
                {
                    Sql = "ALTER DATABASE CURRENT SET READ_COMMITTED_SNAPSHOT ON",
                    SuppressTransaction = true
                },
                new MigrationStatement
                {
                    Sql = "ALTER DATABASE CURRENT SET ALLOW_SNAPSHOT_ISOLATION ON",
                    SuppressTransaction = true
                }
            };
            statements.AddRange(base.Generate(migrationOperations, providerManifestToken));
            return statements;
        }
    }
}

注意:这当然会在2012之前的Sql Server版本上失败,因此要使脚本变得更加强大,因为它需要设置这些标志。这适用于我的具体情况。