EF 코어 다중 데이터베이스 공급자
나의 최근 프로젝트에서, 우리는 서로 다른 배치 환경을 지원하기 위해 여러 공급자를 추가해야 한다.일부 고객은 Windows Server와 SQL Server 데이터베이스를 더 좋아하고, 다른 일부 고객은 Linux와 MySQL 또는 PostgreSQL을 더 좋아한다.
이 연습에서는 SQL Server와 PostgresSQL 제공 프로그램을 추가하고 구성하는 방법을 보여 드리겠습니다.기본 공급자는 SQL Server이고 대체 공급자는 PostgreSQL입니다.
단계 1 - 프로젝트 만들기
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"); })
나는 Data
의 ConfigureService
방법에서 공급자를 구성했다.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
폴더Add-Migration InitialDbMsSql -Context MsSqlDbContext -OutputDir Data\Migrations\MsSql
PostgreSQL 데이터베이스에 대한 마이그레이션을 생성합니다.appsettings.json
추가ConfigureServices
폴더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);
}
}
위 구성에서는 Data
및 appsettings.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)
});
}
}
MsSql
의Configurations
방법 중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);
}
Configurations
또는 WeatherForecastMsSqlConfiguration
Reference
이 문제에 관하여(EF 코어 다중 데이터베이스 공급자), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/moesmp/ef-core-multiple-database-providers-3gb7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)