Reputation: 163
Currently, in my entity I have the following table definition:
[Table("SchemaName.SomeTable")]
I need to be able to change this schema name at run-time. I tried assigning a variable however it throws an error.
As a second attempt I removed the Table
declaration and instead in the OnModelCreating
of my context tried to set it with the following:
modelBuilder.Entity<MY_VIEW>().ToTable("MYSCHEMA.MYVIEW");
This works, however, I would now like to be able to change this at run time through my controller as OnModelCreating only fires once.
Upvotes: 0
Views: 299
Reputation: 15015
In order to make OnModelCreating
to run for different schema you need to override the default behavior for 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();
}
Upvotes: 0