2013-02-05 5 views
14

Podczas próby implementacji Migracji EF w moim projekcie utknąłem w jednym miejscu.Kod EF Najpierw MigrateDatabaseToLatestVersion akceptuje ciąg znaków Nazwa z konfiguracji

Kod EF Najpierw MigrateDatabaseToLatestVersion akceptuje nazwę ciągu połączenia z config.

W moim przypadku nazwa bazy danych jest znana w środowisku wykonawczym (użytkownik wybiera ją z menu rozwijanego). Tylko droga DbContext albo akceptuje, ConnectionString lub connectionString Nazwa w jego konstruktora „MigrateDatabaseToLatestVersion” nie akceptuje samo

System.Data.Entity.Database.SetInitializer 
(new MigrateDatabaseToLatestVersion<SrcDbContext, SRC.DomainModel.ORMapping.Migrations.Configuration>(connString)); 

Czy istnieje inny sposób osiągnięcia tego celu?

+0

możesz przekazać Dynamic ConnectionStringName do kontekstu podczas tworzenia instancji. Przekaż kontekst do inicjatora. Dlaczego trzeba tu przejść? SrcDBConText powinien zostać utworzony za pomocą połączenia podobne. Database.SetInitializer (new MigrateDatabaseToLatestVersion ()); powinno wystarczyć –

+0

-Dziękuję. Próbowałem też tego. Tworzy bazę danych o nazwie {0}, która znajduje się w moim pliku konfiguracyjnym. Chcę użyć MigrateDatabaseToLatestVersion, a nie zwykłego starego inicjalizatora, w którym będę musiał utrzymywać dwie kopie inicjalizacji (jedna do migracji, druga do nowego tworzenia DB). Tworzę wyjątkowe ograniczenia w migracji. –

+0

DbContext można przekazać ciąg połączenia lub nazwę połączenia. Robię dokładnie to samo, co planujesz zrobić. Kontekst 1 używał ponownie wielu baz danych do migracji. Następnie wiele kontekstów Bounded z initializer = null uzyskuje dostęp do DB. Nie wiem, dlaczego to nie działa, przepraszam. –

Odpowiedz

11

Dziękuję wszystkim. Zrobiłem kasę kodu EF z codeplex i odziedziczyłem własną klasę po zrozumieniu ich kodu źródłowego. Oto rozwiązanie, które zdecydowałem: -

public class MigrateDbToLatestInitializerConnString<TContext, TMigrationsConfiguration> : IDatabaseInitializer<TContext> 
     where TContext : DbContext 
     where TMigrationsConfiguration : DbMigrationsConfiguration<TContext>, new() 
    { 
     private readonly DbMigrationsConfiguration config; 

     /// <summary> 
     ///  Initializes a new instance of the MigrateDatabaseToLatestVersion class. 
     /// </summary> 
     public MigrateDbToLatestInitializerConnString() 
     { 
      config = new TMigrationsConfiguration(); 
     } 

     /// <summary> 
     ///  Initializes a new instance of the MigrateDatabaseToLatestVersion class that will 
     ///  use a specific connection string from the configuration file to connect to 
     ///  the database to perform the migration. 
     /// </summary> 
     /// <param name="connectionString"> connection string to use for migration. </param> 
     public MigrateDbToLatestInitializerConnString(string connectionString) 
     { 
      config = new TMigrationsConfiguration 
          { 
           TargetDatabase = new DbConnectionInfo(connectionString, "System.Data.SqlClient") 
          }; 
     } 

     public void InitializeDatabase(TContext context) 
     { 
      if (context == null) 
      { 
       throw new ArgumentException("Context passed to InitializeDatabase can not be null"); 
      } 

      var migrator = new DbMigrator(config); 

      migrator.Update(); 
     } 
    } 

public static class DatabaseHelper 
    { 
     /// <summary> 
     /// This method will create data base for given parameters supplied by caller. 
     /// </summary> 
     /// <param name="serverName">Name of the server where database has to be created</param> 
     /// <param name="databaseName">Name of database</param> 
     /// <param name="userName">SQL user name</param> 
     /// <param name="password">SQL password</param> 
     /// <returns>void</returns> 
     public static bool CreateDb(string serverName, string databaseName, string userName, string password) 
     { 
      bool integratedSecurity = !(!string.IsNullOrEmpty(userName) || !string.IsNullOrEmpty(password)); 

      var builder = new System.Data.SqlClient.SqlConnectionStringBuilder 
       { 
        DataSource = serverName, 
        UserID = userName, 
        Password = password, 
        InitialCatalog = databaseName, 
        IntegratedSecurity = integratedSecurity, 
       }; 


      var db = new SrcDbContext(builder.ConnectionString); 

      var dbInitializer = new MigrateDbToLatestInitializerConnString<SrcDbContext, SRC.DomainModel.ORMapping.Migrations.Configuration>(builder.ConnectionString); 

      //following uses strategy to "CreateIfNotExist<>" 
      dbInitializer.InitializeDatabase(db); 

      return true; 

     } 
    } 
+0

Dzięki ... ładny kawałek przykładowego kodu. Rozwiązałem wiele moich problemów. – Brian

3

W jakim kontekście to działa? Strona internetowa lub aplikacja na komputer?

Na stronie internetowej, nie jest to dobry pomysł. Strategia inicjowania bazy danych jest ustawiona na podstawie rodzaju kontekstu. Tak więc różne ciągi połączeń z tym samym typem kontekstu będą nadpisywać strategię inicjacji drugiej.

Czy w przypadku aplikacji na komputer może być dostępne dodatkowe narzędzie do przełączania się między bazą danych?

W każdym razie nie polecam tego, ale jeśli naprawdę chcesz zrobić to, o czym wspomniałeś, wygląda na to, że musisz to zhackować.

using (var context = new DbContext("<Your connection string right in here>")) 
    { 
     var constructors = typeof (DbMigrator).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic); 
     var hackedDbMigrator = constructors[0].Invoke(new object[] { new Configuration(), context }) as DbMigrator; 
     hackedDbMigrator.Update(); 
    } 
1

Można dokonać inicjator MigrateDatabaseToLatestVersion korzystania z ciąg połączenia, który został użyty przez kontekst, które spowodowało migrację w pierwszej kolejności. Wykonuje się to, przekazując useSuppliedContext: true do konstruktora MigrateDatabaseToLatestVersion, jak opisano w the docs. W twoim przypadku:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<SrcDbContext, SRC.DomainModel.ORMapping.Migrations.Configuration>(useSuppliedContext: true)); 
+0

Dzięki! Jak to nie jest domyślne zachowanie?! ?? – Ergwun