2015-09-08 13 views
14

Şema adı geçişler koduna dahil edildiğinden ve Oracle için şema adı da kullanıcı adı olduğundan Oracle veritabanlarını hedefleyen Entity Framework geçişlerini kullanarak sorunlarım var. Amacım, şemadan bağımsız Kod İlk Geçişleri'nin (test ve üretim ortamları için bir grup geçişe sahip olabilmesi) olması.Şema bağımsız Varlık Çerçeve Kodu İlk Geçişler

Zaten (Entity Framework 6.1.3 kullanarak) bu yaklaşımı denedi

: Web.config,

1) Ben şema adı:

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

2) My DBContext bir şema adını alır yapıcı parametresi:

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

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

3) Ben parametresiz yapıcı yok benim DBContext oluşturmak edebilmek için Varlık Framework Göçler IDbContextFactory uygulamak zorunda:

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

4) Ayrıca geçiş Geçmişi Tablo yapılandırılmış doğru şema içinde yerleştirilmek üzere:

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

5) bir kodlanmış şema adı yerine taşımalar için bir kod modifiye. Örneğin. CreateTable("IPR_TEST.Users")'u CreateTable($"{_schema}.Users") ile değiştirdim. (_schema alanı, Web.config dosyasındaki değere göre ayarlanır).

6) MigrateDatabaseToLatestVersion<EdistributionDbContext, MigrationsConfiguration>() veritabanı başlatıcısını kullanıyorum.

Tüm bu ayarlara sahip olarak, farklı şemaya (ör., Web.config dönüşümü) geçtiğimde hala sorun yaşıyorum - veri tabanımın modelimle eşleşmediğini ve OtomatikMetgrasyonların devre dışı olduğunu bildiren bir istisna atılıyor (İstenen). Ben yeni bir göç oluşturulur add-migration yürütmeye çalıştığınızda tüm nesne farklı şema taşınmış olması gereken yerde (örn:. Kesinlikle arzu edilmez MoveTable(name: "IPR_TEST.DistSetGroups", newSchema: "IPR"); Benim için

o şema adı sabit kablolu modeli dizesi bir yerdedir görünüyor (. örn 201509080802305_InitialCreate.resx) göç sınıfında -HASH, yani:

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

orada şema adını görmezden Kod İlk Migrations anlatmak için nasıl bir yol

+0

Bunu denediğinize eminim, ancak SQL sunucusunda, yalnızca model bağlamalarında şema belirtmezseniz, yalnızca kullanıcı için varsayılan şema kullanılır. –

+2

Teşekkür ederiz @Ben, yorumunuz benim sorunumun bir çözümüne yol açabilir. ModelBuilder.HasDefaultSchema ("SCHEMA_NAME") öğesini atladığınızda; Varlık Çerçevesi, varsayılan şema olarak "dbo" değerini ayarlar. Ancak, şimdi modelBuilder.HasDefaultSchema (string.Empty) 'yi denedim ve şimdi kullanıcı için varsayılan şema (doğru şekilde) kullanılıyor. Ne yazık ki, geçişler için SQL oluşturmak için kullanılan Oracle.ManagedDataAccess.EntityFramework.OracleMigrationSqlGenerator', 'string.Empty'-şema-adı ile sorun var ve göçün SQL oluştururken istisnalar atar ... Ama bu başka bir sorun ... –

+0

Merhaba Jan Palas, bu sorun hakkında herhangi bir çözüm buldunuz mu? Ben aynı sorunu exaclty, ben Oracle ile EF Migration kullanın ve şemayı değiştirdiğimde tüm taşıma komut dosyası MoveTable içerir ... – toregua

cevap

1

bir türetilmiş DbContext ve "geçersiz kılma oluşturabilirim? "OnModelCreating: modelBuilder.HasDefaultSchema(...):

Daha sonra, her iki içerik için de geçişler oluşturabilirsiniz. Bir projede iki geçişin nasıl oluşturulacağıyla ilgili this question numaralı makaleye bakın.

Bu yaklaşımın olumsuz tarafı, iki ayrı geçişi sürdürmeniz gerektiğidir. Ancak size TestDbContext'un yapılandırmasını ayarlama fırsatı verir.

1) Web şema adı var:

1

ben nihayet oldukça iyi iş gibi görünüyor bir çözüm bulduk aynı sorunu ve yaklaşımın için teşekkür karşı karşıya geldi.yapılandırma uygulaması ayarları:

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); 
    } 
} 

3) benim tarih db bağlamını referans bir db yapılandırmasına sahip: Bana tarih bağlamı var

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

2)

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

4) Ve bu benim db içeriğim:

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); 
    } 
} 

5) Sonunda global.asax anahtar String.Empty db bağlam ve doğru olana tarih bağlamın şemanın varsayılan şemayı ayarlamaktır

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

den başlatma yöntemini çağırın. Bu nedenle, geçişlerinizi oluşturduğunuzda bunlar bağımsız şemalardır: Göçün resx'inin DefaultSchema değişkeni boş olacaktır. Ancak geçmiş db içerik şeması, geçiş kontrollerinin geçmesine izin vermek için hala doğrudur.

aşağıdaki nugets paketleri kullanıyorum:

<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" /> 

Ardından, farklı veritabanları üzerinde başarı ile Oracle göçler kullanabilirsiniz.

+0

Çalışmak için onaylandı.Şema adını yalnızca HistoryDbContext'te ayarlamak, farkı yaratan ve herşeyi yerine oturtmaya yarayan farktır. Akıcı yapılandırmalar/veri ek açıklamaları kullanırsanız ve bu yaklaşımı kullanmak istiyorsanız, * şema adını akıcı yapılandırmalarınızda/veri ek açıklamalarınızda ayarladığınızdan emin olmanız gerektiğinin altını çizmek isterim. sadece şema adını boş dizeye bırakın). – xDisruptor