I\'m trying to set up my dbContext so that it can handle multiple schemas in a single Oracle database. I didn\'t want one monolithic dbContext file so I\'ve come up with the
You can specify schema per table via Table
attribute.
[Table(nameof(MyTable1), Schema = "Schema1")]
public class MyTable1 { }
[Table(nameof(MyTable2), Schema = "Schema2")]
public class MyTable2 { }
Try using partial classes instead
public partial class oraDbContext : DbContext
{
static oraDbContext() {
Database.SetInitializer<oraDbContext>(null);
}
public oraDbContext(string connName)
: base("Name=" + connName) { }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
schema1(modelBuilder);
schema2(modelBuilder);
}
}
public partial class oraDbContext : DbContext
{
public DbSet<someTable> someTable { get; set; }
void schema1(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new someTableMap());
}
}
While doing some research about Entity Framework I came across the following post:
http://romiller.com/2011/05/23/ef-4-1-multi-tenant-with-code-first/
It doesn't quite give me a single dbContext to work with but it does only use a single connection (which was my reasoning behind not wanting to use multiple dbContexts). After setting up the following code:
public class oraDbContext : DbContext
{
static oraDbContext() {
Database.SetInitializer<oraDbContext>(null);
}
private oraDbContext(DbConnection connection, DbCompiledModel model)
: base(connection, model, contextOwnsConnection: false) { }
public DbSet<SomeTable1> SomeTable1 { get; set; }
public DbSet<SomeTable2> SomeTable2 { get; set; }
private static ConcurrentDictionary<Tuple<string, string>, DbCompiledModel> modelCache = new ConcurrentDictionary<Tuple<string, string>, DbCompiledModel>();
public static oraDbContext Create(string schemaName, DbConnection connection) {
var compiledModel = modelCache.GetOrAdd(
Tuple.Create(connection.ConnectionString, schemaName),
t =>
{
var builder = new DbModelBuilder();
builder.Configurations.Add<SomeTable1>(new SomeTable1Map(schemaName));
builder.Configurations.Add<SomeTable2>(new SomeTable2Map(schemaName));
var model = builder.Build(connection);
return model.Compile();
});
return new oraDbContext(connection, compiledModel);
}
}
This of course requires that my mapping files be set up like so:
public class DailyDependencyTableMap : EntityTypeConfiguration<DailyDependencyTable>
{
public SomeTableMap(string schemaName) {
this.ToTable("SOME_TABLE_1", schemaName.ToUpper());
//Map other properties and stuff
}
}
Writing queries that use multiple schemas is somewhat annoying but, for the moment, it does what I need it to do:
using (var connection = new OracleConnection("a connection string")) {
using (var schema1 = oraDbContext.Create("SCHEMA1", connection))
using (var schema2 = oraDbContext.Create("SCHEMA2", connection)) {
var query = ((from a in schema1.SomeTable1 select new { a.Field1 }).ToList())
.Concat((from b in schema2.SomeTable1 select new { b.Field1 }).ToList())
}
}