Entity Framework and multiple schemas
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()) }}
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()); }}