Dynamically changing schema in Entity Framework Core

后端 未结 10 2302
刺人心
刺人心 2020-11-28 09:02

UPD here is the way I solved the problem. Although it\'s likely to be not the best one, it worked for me.


I have an issue with working with EF

10条回答
  •  甜味超标
    2020-11-28 09:10

    Define your contex and pass the schema to the constructor.

    Set the default schema in OnModelCreating

       public class MyContext : DbContext , IDbContextSchema
        {
            private readonly string _connectionString;
            public string Schema {get;}
    
            public MyContext(string connectionString, string schema)
            {
                _connectionString = connectionString;
                Schema = schema;
            }
    
            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            {
                if (!optionsBuilder.IsConfigured)
                {
                    optionsBuilder.ReplaceService();
                    optionsBuilder.UseSqlServer(_connectionString);
                }
    
                base.OnConfiguring(optionsBuilder);
            }
    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.HasDefaultSchema(Schema);
    
                // ... model definition ...
            }
        }
    

    Implement your IModelCacheKeyFactory.

    public class DbSchemaAwareModelCacheKeyFactory : IModelCacheKeyFactory
        {
    
            public object Create(DbContext context)
            {
                return new {
                    Type = context.GetType(),
                    Schema = context is IDbContextSchema schema 
                        ? schema.Schema 
                        :  null
                };
            }
        }
    

    Replace in OnConfiguring the default implementation of IModelCacheKeyFactory with your custom implementation.

    With the default implementation of IModelCacheKeyFactory the method OnModelCreating is executed only the first time the context is instantiated and then the result is cached. Changing the implementation you can modify how the result of OnModelCreating is cached and retrieve. Including the schema in the caching key you can get the OnModelCreating executed and cached for every different schema string passed to the context constructor.

    // Get a context referring SCHEMA1
    var context1 = new MyContext(connectionString, "SCHEMA1");
    // Get another context referring SCHEMA2
    var context2 = new MyContext(connectionString, "SCHEMA2");
    

提交回复
热议问题