programing

스키마 독립 엔티티 프레임워크 코드 첫 번째 마이그레이션

muds 2023. 7. 20. 22:11
반응형

스키마 독립 엔티티 프레임워크 코드 첫 번째 마이그레이션

스키마 이름이 마이그레이션 코드에 포함되어 있고 Oracle의 경우 스키마 이름도 사용자 이름이므로 Oracle 데이터베이스를 대상으로 하는 Entity Framework 마이그레이션을 사용하는 데 문제가 있습니다.스키마에 독립적인 코드 우선 마이그레이션(테스트 및 프로덕션 환경을 위해 하나의 마이그레이션 세트를 사용할 수 있음)을 수행하는 것이 목표입니다.

저는 이미 이 접근법을 시도했습니다(Entity Framework 6.1.3 사용).

Web.config에 스키마 이름이 있습니다.

<add key="SchemaName" value="IPR_TEST" />

내 DbContext는 스키마 이름을 생성자 매개 변수로 사용합니다.

public EdistributionDbContext(string schemaName) 
    : base("EdistributionConnection")
{
    _schemaName = schemaName;
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema(_schemaName);
}

매개 변수 없는 생성자가 없는 내 DbContext를 만들기 위해 IDbContextFactory for Entity Framework Migrations를 구현해야 했습니다.

public class MigrationsContextFactory : IDbContextFactory<EdistributionDbContext>
{
    public EdistributionDbContext Create()
    {
        return new EdistributionDbContext(GetSchemaName());
    }
}

또한 마이그레이션 기록 테이블을 올바른 스키마 내에 배치하도록 구성했습니다.

public class EdistributionDbConfiguration : DbConfiguration
{
    public EdistributionDbConfiguration()
    {
        SetDefaultHistoryContext((connection, defaultSchema) 
            => new HistoryContext(connection, GetSchemaName()));
    }
}

하드코딩된 스키마 이름을 대체하기 위해 마이그레이션에 대해 생성된 코드를 수정했습니다.예. 교체했습니다.CreateTable("IPR_TEST.Users")와 함께CreateTable($"{_schema}.Users"). (_schema필드는 Web.config)의 값에 따라 설정됩니다.

사용합니다MigrateDatabaseToLatestVersion<EdistributionDbContext, MigrationsConfiguration>()데이터베이스 이니셜라이저입니다.

이 모든 것을 설정해도 다른 스키마(예: web.config 변환을 통해)로 전환할 때 여전히 문제가 발생합니다. 데이터베이스가 내 모델과 일치하지 않고 자동 마이그레이션이 비활성화되었다는 예외가 발생합니다(원하는 경우).실행하려고 할 때add-migration모든 개체를 다른 스키마로 이동해야 하는 새 마이그레이션이 생성됩니다(예:MoveTable(name: "IPR_TEST.DistSetGroups", newSchema: "IPR");그것은 절대로 바람직하지 않습니다.

스키마 이름은 마이그레이션 클래스(예: 201509080802305_InitialCreate.resx)의 모델 string-hash 어딘가에서 유선 연결된 것 같습니다.

<data name="Target" xml:space="preserve">
    <value>H4sIAAAAAAAEAO09227jO... </value>
</data> 

코드 퍼스트 마이그레이션에 스키마 이름을 무시하도록 지시하는 방법이 있습니까?

파생 모델을 생성할 수 있습니다.DbContext그리고 "해킹"modelBuilder.HasDefaultSchema(...)OnModelCreating:

public class TestDbContext : ProductionDbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.HasDefaultSchema("TestSchema");
    }
}

그런 다음 두 컨텍스트 모두에 대한 마이그레이션을 작성할 수 있습니다.한 프로젝트에서 두 개의 마이그레이션을 생성하는 방법에 대한 이 질문을 참조하십시오.

이 접근 방식의 단점은 두 번의 마이그레이션을 별도로 유지해야 한다는 것입니다.그러나 이를 통해 고객의 구성을 조정할 수 있습니다.TestDbContext.

저는 같은 문제에 직면했고 당신의 접근 방식 덕분에 마침내 잘 작동하는 것 같은 해결책을 찾았습니다.

웹.config 앱 설정에 스키마 이름이 있습니다.

<add key="Schema" value="TEST" />

기록 컨텍스트가 있습니다.

public class HistoryDbContext : HistoryContext
{
    internal static readonly string SCHEMA;

    static HistoryDbContext()
    {
        SCHEMA = ConfigurationManager.AppSettings["Schema"];
    }

    public HistoryDbContext(DbConnection dbConnection, string defaultSchema)
            : base(dbConnection, defaultSchema)
    { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.HasDefaultSchema(SCHEMA);
    }
}

기록 DB 컨텍스트를 참조하는 DB 구성이 있습니다.

public class MyDbConfiguration : DbConfiguration
{
    public MyDbConfiguration()
    {
        SetDefaultHistoryContext((connection, defaultSchema) => new HistoryDbContext(connection, defaultSchema));
    }
}

다음은 제 DB 컨텍스트입니다.

public partial class MyDbContext : DbContext
{
    public MyDbContext()
        : base("name=MyOracleDbContext")
    { }

    public static void Initialize()
    {
        DbConfiguration.SetConfiguration(new MyDbConfiguration());
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, Migrations.Configuration>());
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema(string.Empty);
    }
}

마지막으로 global.asax에서 Initialize 메서드를 호출합니다.

protected void Application_Start()
{
    MyDbContext.Initialize();
}

핵심은 DB 컨텍스트의 기본 스키마를 String으로 설정하는 것입니다.비어 있고 기록 컨텍스트의 스키마가 올바른 컨텍스트로 이동합니다.따라서 마이그레이션을 생성할 때 스키마에 독립적입니다. 마이그레이션의 resx의 DefaultSchema 변수는 비어 있습니다.그러나 history db 컨텍스트 스키마는 마이그레이션 검사를 통과할 수 있도록 여전히 올바릅니다.

다음 너겟 패키지를 사용하고 있습니다.

<package id="EntityFramework" version="6.2.0" targetFramework="net452" />
<package id="Oracle.ManagedDataAccess" version="12.2.1100" targetFramework="net452" />
<package id="Oracle.ManagedDataAccess.EntityFramework" version="12.2.1100" targetFramework="net452" />

그런 다음 다른 데이터베이스에서 오라클 마이그레이션을 성공적으로 사용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/32457006/schema-independent-entity-framework-code-first-migrations

반응형