2013-02-05 10 views
14

Beim Versuch, EF Migrations in meinem Projekt zu implementieren, stehe ich an einer Stelle fest.EF-Code zuerst MigrateDatabaseToLatestVersion akzeptiert Verbindungszeichenfolge Name aus der Konfiguration

EF-Code zuerst MigrateDatabaseToLatestVersion akzeptiert Verbindungszeichenfolge Name von config.

In meinem Fall Datenbankname bekannt zur Laufzeit (Benutzer wählt es aus Dropdown). Genau so, wie DbContext entweder akzeptiert, oder Connectionconnection Namen in seinem Konstruktor „MigrateDatabaseToLatestVersion“ akzeptiert nicht die gleichen

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

Gibt es eine andere Möglichkeit, dies zu erreichen?

+0

können Sie Dynamic ConnectionStringName während der Instantiierung in den Kontext übergeben. Sie übergeben den Kontext an den Initialisierer. Warum die Notwendigkeit, hier vorbei zu gehen? SrcDBConText sollte mit Connection wie like erstellt werden. Database.SetInitializer (neue MigrateDatabaseToLatestVersion ()); sollte genug sein –

+0

-Danke. Ich habe das auch versucht. Es erstellt db mit dem Namen {0}, der sich in meiner Konfigurationsdatei befindet. Ich möchte MigrateDatabaseToLatestVersion und nicht Plain Old Initializer verwenden, wo ich zwei Kopien der Initialisierung (eine für die Migration, eine andere für die neue DB-Erstellung) beibehalten muss. Ich erstelle einzigartige Einschränkungen bei der Migration. –

+0

DbContext kann eine Verbindungszeichenfolge oder einen Verbindungsnamen übergeben werden. Ich mache genau dasselbe, was du planst zu tun. 1 Kontext verwendet wieder mehrere DBs für die Migration. Dann greifen viele beschränkte Kontexte mit initializer = null auf die DBs zu. Ich bin mir nicht sicher, warum es nicht für dich tut. –

Antwort

11

Danke euch allen. Ich habe den EF-Code aus Codeplex ausgecheckt und meine eigene Klasse geerbt, nachdem ich ihren Quellcode verstanden hatte. Hier ist die Lösung, die ich entschieden: -

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

Danke ... schönes Stück Beispielcode. Viele meiner Probleme gelöst. – Brian

3

In welchem ​​Kontext läuft das? Website oder Desktop App?

Unter Website, das ist keine gute Idee. Die Datenbankinitialisierungsstrategie wird dem Kontexttyp zugeordnet. Daher überschreiben unterschiedliche Verbindungszeichenfolgen mit demselben Kontexttyp die Init-Strategie des jeweils anderen.

Wenn Desktop-App, möglicherweise ein zusätzliches Dienstprogramm, um zwischen der Datenbank wechseln?

In jedem Fall empfehle ich nicht, dies zu tun, aber wenn Sie wirklich tun wollen, was Sie erwähnten, sieht es so aus, als ob Sie es hacken müssen.

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

Sie den MigrateDatabaseToLatestVersion initializer machen können die Verbindungszeichenfolge zu verwenden, die durch den Kontext verwendet wurden, die die Migration in erster Linie ausgelöst. Dies geschieht, indem useSuppliedContext: true an den MigrateDatabaseToLatestVersion-Konstruktor übergeben wird, wie in the docs beschrieben. In Ihrem Fall:

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

Danke! Wie ist das nicht das Standardverhalten ??! ?? – Ergwun

Verwandte Themen