与架构无关的实体框架代码优先迁移 [英] Schema independent Entity Framework Code First Migrations

查看:92
本文介绍了与架构无关的实体框架代码优先迁移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于在迁移代码中包含了架构名称,因此在使用针对Oracle数据库的Entity Framework迁移时遇到麻烦,对于Oracle,架构名称也是用户名.我的目标是进行与模式无关的代码优先"迁移(以便能够针对测试和生产环境进行一组迁移).

I have troubles using Entity Framework migrations targeting Oracle databases since schema name is included in migrations code and for Oracle, schema name is also user name. My goal is to have schema-independent Code First Migrations (to be able to have one set of migrations for testing and production enviroments).

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

I have already tried this approach (using Entity Framework 6.1.3):

1)我在Web.config中有架构名称:

1) I have schema name in Web.config:

<add key="SchemaName" value="IPR_TEST" />

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

2) My DbContext takes schema name as a constructor parameter:

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

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema(_schemaName);
}

3)我必须为实体框架迁移实现IDbContextFactory才能创建没有无参数构造函数的DbContext:

3) I had to implement IDbContextFactory for Entity Framework Migrations to be able to create my DbContext which does not have parameterless constructor:

public class MigrationsContextFactory : IDbContextFactory<EdistributionDbContext>
{
    public EdistributionDbContext Create()
    {
        return new EdistributionDbContext(GetSchemaName());
    }
}

4)我还配置了迁移历史记录表"以放置在正确的架构内:

4) I also configured Migration History Table to be placed within correct schema:

public class EdistributionDbConfiguration : DbConfiguration
{
    public EdistributionDbConfiguration()
    {
        SetDefaultHistoryContext((connection, defaultSchema) 
            => new HistoryContext(connection, GetSchemaName()));
    }
}

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

5) I modified code generated for migrations to replace hardcoded schema name. Eg. I replaced CreateTable("IPR_TEST.Users") with CreateTable($"{_schema}.Users"). (_schema field is set according to the value in Web.config).

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

6) I use MigrateDatabaseToLatestVersion<EdistributionDbContext, MigrationsConfiguration>() database initializer.

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

Having all this set up, I still have problems when I switch to different schema (eg. via web.config transformation) - an exception is thrown telling me that database does not match my model and AutomaticMigrations are disabled (which is desired). When I try to execute add-migration a new migration is generated where all object should be moved to different schema (eg: MoveTable(name: "IPR_TEST.DistSetGroups", newSchema: "IPR");, which is definitely not desired.

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

For me it seems that schema name is hard-wired somewhere in model string-hash in migration class (eg. 201509080802305_InitialCreate.resx), ie:

<data name="Target" xml:space="preserve">
    <value>H4sIAAAAAAAEAO09227jO... </value>
</data> 

有没有办法告诉代码优先迁移忽略模式名称?

It there a way how to tell Code First Migrations to ignore schema name?

推荐答案

您可以在OnModelCreating中创建派生的DbContext和替代" modelBuilder.HasDefaultSchema(...):

You can create a derived DbContext and "override" modelBuilder.HasDefaultSchema(...) in OnModelCreating:

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

        modelBuilder.HasDefaultSchema("TestSchema");
    }
}

然后,您可以为两个上下文创建迁移.有关如何在一个项目中创建两个迁移的信息,请参见此问题.

Then you can create migrations for both contexts. See this question on how to create two migrations in one project.

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

The downside of this approach is that you have to maintain two seperate migrations. But it gives you the opportunity to adjust the configuration of your TestDbContext.

这篇关于与架构无关的实体框架代码优先迁移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆