模式独立的实体框架代码第一次迁移

Jan*_*las 14 c# oracle entity-framework ef-migrations

我很难使用针对Oracle数据库的Entity Framework迁移,因为模式名称包含在迁移代码中,而对于Oracle,模式名称也是用户名.我的目标是实现与模式无关的Code First Migrations(能够为测试和生产环境提供一组迁移).

我已经尝试过这种方法(使用Entity Framework 6.1.3):

1)我在Web.config中有模式名称:

<add key="SchemaName" value="IPR_TEST" />
Run Code Online (Sandbox Code Playgroud)

2)我的DbContext将模式名称作为构造函数参数:

public EdistributionDbContext(string schemaName) 
    : base("EdistributionConnection")
{
    _schemaName = schemaName;
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema(_schemaName);
}
Run Code Online (Sandbox Code Playgroud)

3)我必须为Entity Framework Migrations实现IDbContextFactory才能创建没有无参数构造函数的DbContext:

public class MigrationsContextFactory : IDbContextFactory<EdistributionDbContext>
{
    public EdistributionDbContext Create()
    {
        return new EdistributionDbContext(GetSchemaName());
    }
}
Run Code Online (Sandbox Code Playgroud)

4)我还将迁移历史表配置为正确的模式:

public class EdistributionDbConfiguration : DbConfiguration
{
    public EdistributionDbConfiguration()
    {
        SetDefaultHistoryContext((connection, defaultSchema) 
            => new HistoryContext(connection, GetSchemaName()));
    }
}
Run Code Online (Sandbox Code Playgroud)

5)我修改了为迁移生成的代码,以替换硬编码的模式名称.例如.我替换CreateTable("IPR_TEST.Users")CreateTable($"{_schema}.Users").(_schema字段根据Web.config中的值设置).

6)我使用MigrateDatabaseToLatestVersion<EdistributionDbContext, MigrationsConfiguration>()数据库初始化程序.

完成所有这些设置后,当我切换到不同的模式时(例如,通过web.config转换),我仍然会遇到问题 - 抛出一个异常,告诉我数据库与我的模型不匹配,并且AutomaticMigrations被禁用(这是所需的).当我尝试执行add-migration新的迁移时,会生成所有对象应该移动到不同的模式(例如:MoveTable(name: "IPR_TEST.DistSetGroups", newSchema: "IPR");,这绝对不是所希望的).

对我来说,似乎架构名称在迁移类中的模型字符串哈希中是硬连接的(例如,201509080802305_InitialCreate.resx),即:

<data name="Target" xml:space="preserve">
    <value>H4sIAAAAAAAEAO09227jO... </value>
</data> 
Run Code Online (Sandbox Code Playgroud)

有没有办法告诉Code First Migrations忽略模式名称?

Pet*_*erB 4

您可以在以下位置创建派生DbContext和“覆盖” :modelBuilder.HasDefaultSchema(...)OnModelCreating

public class TestDbContext : ProductionDbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.HasDefaultSchema("TestSchema");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以为这两个上下文创建迁移。请参阅此问题,了解如何在一个项目中创建两个迁移。

这种方法的缺点是您必须维护两个单独的迁移。但它使您有机会调整TestDbContext.