Dynamically changing schema in Entity Framework Core

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

    Did you already use EntityTypeConfiguration in EF6?

    I think the solution would be use mapping for entities on OnModelCreating method in DbContext class, something like this:

    using System;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal;
    using Microsoft.Extensions.Options;
    
    namespace AdventureWorksAPI.Models
    {
        public class AdventureWorksDbContext : Microsoft.EntityFrameworkCore.DbContext
        {
            public AdventureWorksDbContext(IOptions appSettings)
            {
                ConnectionString = appSettings.Value.ConnectionString;
            }
    
            public String ConnectionString { get; }
    
            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            {
                optionsBuilder.UseSqlServer(ConnectionString);
    
                // this block forces map method invoke for each instance
                var builder = new ModelBuilder(new CoreConventionSetBuilder().CreateConventionSet());
    
                OnModelCreating(builder);
    
                optionsBuilder.UseModel(builder.Model);
            }
    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.MapProduct();
    
                base.OnModelCreating(modelBuilder);
            }
        }
    }
    

    The code on OnConfiguring method forces the execution of MapProduct on each instance creation for DbContext class.

    Definition of MapProduct method:

    using System;
    using Microsoft.EntityFrameworkCore;
    
    namespace AdventureWorksAPI.Models
    {
        public static class ProductMap
        {
            public static ModelBuilder MapProduct(this ModelBuilder modelBuilder, String schema)
            {
                var entity = modelBuilder.Entity();
    
                entity.ToTable("Product", schema);
    
                entity.HasKey(p => new { p.ProductID });
    
                entity.Property(p => p.ProductID).UseSqlServerIdentityColumn();
    
                return modelBuilder;
            }
        }
    }
    

    As you can see above, there is a line to set schema and name for table, you can send schema name for one constructor in DbContext or something like that.

    Please don't use magic strings, you can create a class with all available schemas, for example:

    using System;
    
    public class Schemas
    {
        public const String HumanResources = "HumanResources";
        public const String Production = "Production";
        public const String Sales = "Sales";
    }
    

    For create your DbContext with specific schema you can write this:

    var humanResourcesDbContext = new AdventureWorksDbContext(Schemas.HumanResources);
    
    var productionDbContext = new AdventureWorksDbContext(Schemas.Production);
    

    Obviously you should to set schema name according schema's name parameter's value:

    entity.ToTable("Product", schemaName);
    

提交回复
热议问题