Dynamically changing schema in Entity Framework Core

后端 未结 10 2279
刺人心
刺人心 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:18

    I find this blog might be useful for you. Perfect !:)

    https://romiller.com/2011/05/23/ef-4-1-multi-tenant-with-code-first/

    This blog is based on ef4, I'm not sure whether it will work fine with ef core.

    public class ContactContext : DbContext
    {
        private ContactContext(DbConnection connection, DbCompiledModel model)
            : base(connection, model, contextOwnsConnection: false)
        { }
    
        public DbSet People { get; set; }
        public DbSet ContactInfo { get; set; }
    
        private static ConcurrentDictionary, DbCompiledModel> modelCache
            = new ConcurrentDictionary, DbCompiledModel>();
    
        /// 
        /// Creates a context that will access the specified tenant
        /// 
        public static ContactContext Create(string tenantSchema, DbConnection connection)
        {
            var compiledModel = modelCache.GetOrAdd(
                Tuple.Create(connection.ConnectionString, tenantSchema),
                t =>
                {
                    var builder = new DbModelBuilder();
                    builder.Conventions.Remove();
                    builder.Entity().ToTable("Person", tenantSchema);
                    builder.Entity().ToTable("ContactInfo", tenantSchema);
    
                    var model = builder.Build(connection);
                    return model.Compile();
                });
    
            return new ContactContext(connection, compiledModel);
        }
    
        /// 
        /// Creates the database and/or tables for a new tenant
        /// 
        public static void ProvisionTenant(string tenantSchema, DbConnection connection)
        {
            using (var ctx = Create(tenantSchema, connection))
            {
                if (!ctx.Database.Exists())
                {
                    ctx.Database.Create();
                }
                else
                {
                    var createScript = ((IObjectContextAdapter)ctx).ObjectContext.CreateDatabaseScript();
                    ctx.Database.ExecuteSqlCommand(createScript);
                }
            }
        }
    }
    

    The main idea of these codes is to provide a static method to create different DbContext by different schema and cache them with certain identifiers.

提交回复
热议问题