EF 코어 다중 데이터베이스 공급자

대부분의 경우 SQL Server 공급자로부터 시작하여 다른 데이터베이스 공급자로 전환할 필요가 없습니다.
나의 최근 프로젝트에서, 우리는 서로 다른 배치 환경을 지원하기 위해 여러 공급자를 추가해야 한다.일부 고객은 Windows Server와 SQL Server 데이터베이스를 더 좋아하고, 다른 일부 고객은 Linux와 MySQL 또는 PostgreSQL을 더 좋아한다.
이 연습에서는 SQL Server와 PostgresSQL 제공 프로그램을 추가하고 구성하는 방법을 보여 드리겠습니다.기본 공급자는 SQL Server이고 대체 공급자는 PostgreSQL입니다.

단계 1 - 프로젝트 만들기
  • ASP를 생성합니다.NET 코어 웹 API

  • 2단계 - 기본 DbContext 만들기
  • 프로젝트의 루트 디렉터리에 Data 폴더 추가
  • 폴더에 WeatherDbContext 추가:
  • public abstract class WeatherDbContext : DbContext
    {
        protected readonly IConfiguration Configuration;
    
        protected WeatherDbContext(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        public DbSet<WeatherForecast> WeatherForecasts { get; set; }
    }
    
    Data는 우리의 기본 DbContext입니다. 우리는 모든 코드에서 이 기본 DbContext를 사용합니다.MsSqlDbContext에는 모든 DbContext 클래스에서 사용하고자 하는 데이터베이스 세트와 공유 기능이 포함되어 있습니다.

    단계 3-SQL Server DbContext 만들기
  • 폴더에 MsSqlDbContext 추가:
  • public class MsSqlDbContext : WeatherDbContext
    {
        public MsSqlDbContext(IConfiguration configuration) : base(configuration)
        {
        }
    
        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlServer(Configuration.GetConnectionString("MsSqlConnection"));
        }
    }
    
  • 클래스가 아닌 MsSqlDbContext 메서드에서 SQL Server Provider를 구성합니다.
  • services.AddDbContext<YourDbContext>(options => { options.UseSqlServer(Configuration.GetConnectionString("SomeConnection"); })
    
    나는 DataConfigureService 방법에서 공급자를 구성했다.
    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        options.UseSqlServer(Configuration.GetConnectionString("MsSqlConnection"));
    }
    

    4단계 - PosgresQL 데이터베이스 컨텍스트 작성
  • 클래스를 Startup 폴더에 추가하려면:
  • public class PostgresDbContext : MsSqlDbContext
    {
        public PostgresDbContext(IConfiguration configuration)
            : base(configuration)
        {
        }
    
        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseNpgsql(Configuration.GetConnectionString("PostgreSqlConnection"));
        }
    }
    

    5단계 DBContext 등록
    지금까지 우리는 두 개의 DBContext를 가지고 있지만, 설정 파일 OnConfiguring 에서 가장 좋은 데이터베이스 제공 프로그램을 선택하기를 희망합니다.
  • MsSqlDbContext에 다음 키/값을 추가합니다.
  • "DatabaseProvider": "MsSql"
    
  • 선택한 공급자에 따라 PostgresDbContext에 데이터베이스 공급자를 등록합니다.
  • public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
    
        switch (Configuration["DatabaseProvider"])
        {
            case "MsSql":
                services.AddDbContext<WeatherDbContext,MsSqlDbContext>();
                break;
    
            case "PostgreSql":
                services.AddDbContext<WeatherDbContext,PostgresDbContext>();
                break;
        }
    }
    

    6단계 - 마이그레이션
    SQL Server 데이터베이스에 대한 마이그레이션을 생성합니다.
  • 폴더에 Data 추가appsettings.json 폴더
  • 파일에서 "DatabaseProvider"키
  • 의 "MsSql"값을 설정합니다.
  • 마이그레이션 SQL Server 데이터베이스를 생성하려면 다음 명령을 실행합니다.
  • Add-Migration InitialDbMsSql -Context MsSqlDbContext -OutputDir Data\Migrations\MsSql
    
    PostgreSQL 데이터베이스에 대한 마이그레이션을 생성합니다.
  • 폴더에 appsettings.json 추가ConfigureServices 폴더
  • 파일에서 DatabaseProvider 키
  • 에 대한 PostgreSql 값을 설정합니다.
  • 마이그레이션 SQL Server 데이터베이스를 생성하려면 다음 명령을 실행합니다.
  • Add-Migration InitialDbPostgres -Context PostgresDbContext -OutputDir Data\Migrations\PostgreSql
    

    4. 솔리드 구성
    다음은 Migrations\MsSql 과정입니다.
    public class WeatherForecast
    {
        public int Id { get; set; }
    
        public DateTime Date { get; set; }
    
        public int TemperatureC { get; set; }
    
        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    
        public string Summary { get; set; }
    }
    
    다음 구성을 고려하십시오.
    internal class WeatherForecastConfiguration : IEntityTypeConfiguration<WeatherForecast>
    {
        public void Configure(EntityTypeBuilder<WeatherForecast> builder)
        {
            builder.Property(wf => wf.TemperatureC).HasColumnType("tinyint");
            builder.Property(wf => wf.Date).HasColumnType("datetime");
            builder.Property(wf => wf.Summary).HasColumnType("nvarchar(512)").IsRequired(false);
            builder.Ignore(wf => wf.TemperatureF);
        }
    }
    
    위 구성에서는 Dataappsettings.json를 사용하여 SQL Server에서 지원되지만 PostgreSQL에서는 지원되지 않습니다.이 경우 구성을 Migrations\PostgreSql 메소드 DbContext로 이동할 수 있습니다.
    public class MsSqlDbContext : DbContext
    {
        ...
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<WeatherForecast>().Property(wf => wf.TemperatureC).HasColumnType("tinyint");
            modelBuilder.Entity<WeatherForecast>().Property(wf => wf.Date).HasColumnType("datetime");
            modelBuilder.Entity<WeatherForecast>().Property(wf => wf.Summary).HasColumnType("nvarchar(512)").IsRequired(false);
        }
    }
    
    PostgresDbContext의 경우:
    public class PostgresDbContext : MsSqlDbContext
    {
        ...
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<WeatherForecast>().Property(wf => wf.TemperatureC).HasColumnType("samllint");
            modelBuilder.Entity<WeatherForecast>().Property(wf => wf.Date).HasColumnType("timestamp(3)");
            modelBuilder.Entity<WeatherForecast>().Property(wf => wf.Summary).HasColumnType("varchar(512)").IsRequired(false);
        }
    }
    
    나는 특정 설정을 Data에서 설정 클래스로 이동하고 반사appsettings.json 방법으로 깨끗하게 유지하는 것을 좋아하지만, 당신은 그대로 유지할 수 있다.
    구성을 이동하려면 다음과 같이 하십시오.
  • 데이터베이스 공급자
  • 의 일반적인 구성을 위한 WeatherForecast 폴더에 tinyint 추가
  • 클래스를 nvarchar 폴더에 추가하려면:
  • internal class WeatherForecastSharedConfiguration : IEntityTypeConfiguration<WeatherForecast>
    {
        public void Configure(EntityTypeBuilder<WeatherForecast> builder)
        {
            builder.Ignore(wf => wf.TemperatureF);
        }
    }
    
  • 폴더에 OnModelCreating 추가OnModelCreating 폴더
  • 클래스를 OnModelCreating 폴더에 추가하려면:
  • internal class WeatherForecastMsSqlConfiguration : IEntityTypeConfiguration<WeatherForecast>
    {
        public void Configure(EntityTypeBuilder<WeatherForecast> builder)
        {
            builder.Property(wf => wf.TemperatureC).HasColumnType("tinyint");
            builder.Property(wf => wf.Date).HasColumnType("datetime");
            builder.Property(wf => wf.Summary).HasColumnType("nvarchar(512)").IsRequired(false);
        }
    }
    
  • 폴더에 Configurations 추가Data 폴더
  • 클래스를 WeatherForecastSharedConfiguration 폴더에 추가하려면:
  • internal class WeatherForecastPostgresConfiguration : IEntityTypeConfiguration<WeatherForecast>
    {
        public void Configure(EntityTypeBuilder<WeatherForecast> builder)
        {
            builder.Property(wf => wf.TemperatureC).HasColumnType("samllint");
            builder.Property(wf => wf.Date).HasColumnType("timestamp(3)");
            builder.Property(wf => wf.Summary).HasColumnType("varchar(512)").IsRequired(false);
        }
    }
    
  • 다음 코드를 Configurations(기본 DbContext)에 추가하여 공유 및 제공 프로그램별 구성을 로드합니다.
  • protected void ApplyConfiguration(ModelBuilder modelBuilder, string[] namespaces)
    {
        var methodInfo = (typeof(ModelBuilder).GetMethods()).Single((e =>
            e.Name == "ApplyConfiguration" &&
            e.ContainsGenericParameters &&
            e.GetParameters().SingleOrDefault()?.ParameterType.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>)));
    
        foreach (var configType in typeof(MsSqlDbContext).GetTypeInfo().Assembly.GetTypes()
    
            .Where(t => t.Namespace != null &&
                        namespaces.Any(n => n == t.Namespace) &&
                        t.GetInterfaces().Any(i => i.IsGenericType &&
                                                   i.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>))))
        {
            var type = configType.GetInterfaces().First();
            methodInfo.MakeGenericMethod(type.GenericTypeArguments[0]).Invoke(modelBuilder, new[]
            {
                Activator.CreateInstance(configType)
            });
        }
    }
    
    MsSqlConfigurations방법 중
  • :
  • protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var namespaces = new[] { "EfMultipleProviders.Data.Configurations",
            "EfMultipleProviders.Data.Configurations.MsSql" };
        ApplyConfiguration(modelBuilder, namespaces);
    }
    
    WeatherForecastMsSqlConfiguration 네임스페이스에서 공유 구성을, MsSql 네임스페이스에서 SQL Server 구성을 로드합니다.
  • PostgreSql:
  • protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var namespaces = new[] { "EfMultipleProviders.Data.Configurations",
            "EfMultipleProviders.Data.Configurations.PostgreSql" };
        ApplyConfiguration(modelBuilder, namespaces);
    }
    
  • 모델Builder를 사용하지 마십시오.ApplyConfigurationsFromAssembly() 메서드가 구성을 로드합니다.
  • WeatherDbContext를 저장소, 서비스 또는 컨트롤러에 주입한다Configurations 또는 WeatherForecastMsSqlConfiguration
  • Github 에서 이 연습의 원본 코드를 찾을 수 있습니다.

    좋은 웹페이지 즐겨찾기