2013-02-05 34 views
14

Trong khi cố gắng triển khai EF Migrations trong dự án của tôi, tôi bị kẹt ở một nơi.Mã EF First MigrateDatabaseToLatestVersion chấp nhận tên chuỗi kết nối từ cấu hình

Mã EF First MigrateDatabaseToLatestVersion chấp nhận chuỗi kết nối Tên từ cấu hình.

Trong trường hợp tên cơ sở dữ liệu của tôi được biết đến tại Thời gian chạy (Người dùng chọn nó từ trình đơn thả xuống). Chỉ cách DbContext hoặc chấp nhận, hoặc ConnectionString connectionString Tên trong constructor của nó, "MigrateDatabaseToLatestVersion" không chấp nhận cùng

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

Có cách nào khác để đạt được điều này?

+0

bạn có thể chuyển Dynamic ConnectionStringName vào Bối cảnh trong quá trình khởi tạo. Bạn chuyển ngữ cảnh đến bộ khởi tạo. Tại sao cần phải vượt qua đây? SrcDBConText nên được tạo với kết nối giống như của bạn. Database.SetInitializer (mới MigrateDatabaseToLatestVersion ()); phải đủ –

+0

-Cảm ơn. Tôi đã thử điều này. Nó tạo ra db với tên {0} trong tệp Config của tôi. Tôi muốn sử dụng MigrateDatabaseToLatestVersion và không phải là trình khởi tạo cũ đơn giản, nơi tôi sẽ phải duy trì hai bản sao khởi tạo (một cho việc di chuyển, một bản sao khác để tạo DB mới). Tôi đang tạo ra các ràng buộc duy nhất trong quá trình di chuyển. –

+0

DbContext có thể được chuyển qua chuỗi kết nối hoặc Tên kết nối. Tôi làm điều tương tự như kế hoạch của bạn để làm. 1 bối cảnh được sử dụng một lần nữa nhiều DB để di chuyển. Sau đó, nhiều bối cảnh bị ràng buộc với initializer = null truy cập các DB. Không chắc chắn lý do tại sao nó không hoạt động cho bạn xin lỗi. –

Trả lời

11

Cảm ơn tất cả. Tôi đã kiểm tra mã EF từ codeplex, và kế thừa lớp của riêng tôi sau khi hiểu mã nguồn của họ. Dưới đây là giải pháp mà tôi đã lựa chọn: -

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

Cảm ơn ... đoạn mã mẫu đẹp. Giải quyết nhiều vấn đề của tôi. – Brian

3

Ngữ cảnh này đang chạy dưới mức nào? Trang web hoặc Ứng dụng dành cho máy tính để bàn?

Theo trang web, làm điều đó không phải là một ý tưởng hay. Chiến lược khởi tạo cơ sở dữ liệu được đặt theo loại ngữ cảnh. Vì vậy, các chuỗi kết nối khác nhau với cùng một loại ngữ cảnh sẽ ghi đè lên chiến lược init của nhau.

Nếu ứng dụng trên máy tính để bàn, có thể bao gồm tiện ích bổ sung để chuyển đổi giữa cơ sở dữ liệu?

Dù bằng cách nào tôi không khuyên bạn nên làm điều này, nhưng nếu bạn thực sự muốn làm những gì bạn đề cập, có vẻ như bạn phải hack nó.

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

Bạn có thể làm cho initializer MigrateDatabaseToLatestVersion sử dụng chuỗi kết nối đã được sử dụng bởi bối cảnh mà gây ra sự di cư ở nơi đầu tiên. Điều này được thực hiện bằng cách chuyển useSuppliedContext: true tới hàm tạo MigrateDatabaseToLatestVersion như được mô tả trong the docs. Trong trường hợp của bạn:

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

Cảm ơn! Làm thế nào đây không phải là hành vi mặc định ??! ?? – Ergwun

Các vấn đề liên quan