Dynamically changing schema in Entity Framework Core

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

    Took several hours to figure this out with EFCore. Seems to be alot of confusion on the proper way of implementing this. I believe the simple and correct way of handling custom models in EFCore is replacing the default IModelCacheKeyFactory service like I show below. In my example I am setting custom table names.

    1. Create a ModelCacheKey variable in your context class.
    2. In your context constructor, set the ModelCacheKey variable
    3. Create a class that inherits from IModelCacheKeyFactory and use ModelCacheKey (MyModelCacheKeyFactory)
    4. In OnConfiguring method (MyContext), replace the default IModelCacheKeyFactory
    5. In OnModelCreating method (MyContext), use the ModelBuilder to define whatever you need.
    public class MyModelCacheKeyFactory : IModelCacheKeyFactory
    {
        public object Create(DbContext context)
            => context is MyContext myContext ?
            (context.GetType(), myContext.ModelCacheKey) :
            (object)context.GetType();
    }
    
    public partial class MyContext : DbContext
    {
         public string Company { get; }
         public string ModelCacheKey { get; }
         public MyContext(string connectionString, string company) : base(connectionString) 
         { 
             Company = company;
             ModelCacheKey = company; //the identifier for the model this instance will use
         }
    
         protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
         {
             //This will create one model cache per key
             optionsBuilder.ReplaceService(entity => 
             { 
                 //regular entity mapping 
             });
    
             SetCustomConfigurations(modelBuilder);
         }
    
         public void SetCustomConfigurations(ModelBuilder modelBuilder)
         {
             //Here you will set the schema. 
             //In my example I am setting custom table name Order_CompanyX
    
             var entityType = typeof(Order);
             var tableName = entityType.Name + "_" + this.Company;
             var mutableEntityType = modelBuilder.Model.GetOrAddEntityType(entityType);
             mutableEntityType.RemoveAnnotation("Relational:TableName");
             mutableEntityType.AddAnnotation("Relational:TableName", tableName);
         }
    }
    

    The result is each instance of your context will cause efcore to cache based on the ModelCacheKey variable.

提交回复
热议问题