在运行时更改数据库架构名称

时间:2019-10-22 13:39:59

标签: c# asp.net oracle entity-framework

当前,在我的实体中,我具有以下表格定义:

[Table("SchemaName.SomeTable")]

我需要能够在运行时更改此架构名称。我尝试分配一个变量,但是会引发错误。

作为第二次尝试,我删除了Table声明,而是在上下文的OnModelCreating中尝试设置以下内容:

modelBuilder.Entity<MY_VIEW>().ToTable("MYSCHEMA.MYVIEW");

这有效,但是,现在我希望能够在运行时通过控制器更改此设置,因为OnModelCreating仅触发一次。

1 个答案:

答案 0 :(得分:0)

为了使OnModelCreating在不同的模式下运行,您需要覆盖IModelCacheKeyFactory的默认行为

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
        {
            options.ReplaceService<IModelCacheKeyFactory, SchemaModelCacheKeyFactory>();
        });
    }
}

public class DatabaseOptions
{
    public string Schema { get; set; }
}

public class ApplicationDbContext : DbContext
{
    public string Schema { get; }

    public ApplicationDbContext(DbContextOptions options, IOptions<DatabaseOptions> databaseOptions)
        : base(options)
    {
        Schema = databaseOptions.Value.Schema;
    }


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MY_VIEW>().ToTable($"{Schema}.MYVIEW");
    }
}

public class SchemaModelCacheKeyFactory : ModelCacheKeyFactory
{
    public SchemaModelCacheKeyFactory(ModelCacheKeyFactoryDependencies dependencies)
        : base(dependencies)
    {
    }

    public override object Create(DbContext context)
    {
        if (context is ApplicationDbContext applicationDbContext)
        {
            return new SchemaModelCacheKey(context, applicationDbContext.Schema);
        }
        else
        {
            return base.Create(context);
        }
    }
}

public class SchemaModelCacheKey : ModelCacheKey
{
    public SchemaModelCacheKey(DbContext context, string schema) : base(context)
    {
        _schema = schema;
    }

    private readonly string _schema;

    protected virtual bool Equals(SchemaModelCacheKey other) => _schema == other._schema && base.Equals(other);

    public override bool Equals(object obj) => (obj is SchemaModelCacheKey otherAsKey) && Equals(otherAsKey);

    public override int GetHashCode() => base.GetHashCode() + _schema.GetHashCode();
}