Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Làm thế nào để tạo trình khởi tạo để tạo và di chuyển cơ sở dữ liệu mysql?

Tôi nghĩ bạn đang ở đó khá nhiều - bạn có thể tra cứu mã nguồn cho MigrateDatabaseToLatestVersion (đó là nguồn mở http://entityframework.codeplex.com/ ) - nó khá đơn giản, những gì nó làm được khá nhiều là gọi DbMigrator - theo như tôi có thể thấy.

Tất cả những gì bạn phải làm dường như là hợp nhất cả hai - sử dụng cái này hoặc cái kia làm cơ sở, thêm chức năng khác vào đó - tôi nghĩ sẽ hoạt động tốt.

class CreateAndMigrateDatabaseInitializer<TContext, TConfiguration> : CreateDatabaseIfNotExists<TContext>, IDatabaseInitializer<TContext> 
    where TContext : DbContext
    where TConfiguration : DbMigrationsConfiguration<TContext>, new()
{
    private readonly DbMigrationsConfiguration _configuration;
    public CreateAndMigrateDatabaseInitializer()
    {
        _configuration = new TConfiguration();
    }
    public CreateAndMigrateDatabaseInitializer(string connection)
    {
        Contract.Requires(!string.IsNullOrEmpty(connection), "connection");

        _configuration = new TConfiguration
        {
            TargetDatabase = new DbConnectionInfo(connection)
        };
    }
    void IDatabaseInitializer<TContext>.InitializeDatabase(TContext context)
    {
        Contract.Requires(context != null, "context");

        var migrator = new DbMigrator(_configuration);
        migrator.Update();

        // move on with the 'CreateDatabaseIfNotExists' for the 'Seed'
        base.InitializeDatabase(context);
    }
    protected override void Seed(TContext context)
    {
    }
}

gọi nó như thế này ...

Database.SetInitializer(new CreateAndMigrateDatabaseInitializer<GumpDatabase, YourNamespace.Migrations.Configuration>());

... thực ra, hãy ghi đè nó (vì nó được triển khai chung) giống như bạn đang làm cho CreateDatabaseIfNotExists (bạn chỉ có thêm 'thông số' cho Cấu hình) - và chỉ cần cung cấp 'Hạt giống'.

class GumpDatabaseInitializer : CreateAndMigrateDatabaseInitializer<GumpDatabase, YourNamespace.Migrations.Configuration>
{
    protected override void Seed(GumpDatabase context)
    {
        context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX Name ON Stations (Name)");
    }
}

... và gọi nó là một cái gì đó giống như

Database.SetInitializer(new GumpDatabaseInitializer());

CHỈNH SỬA: Dựa trên các nhận xét - DbMigrator không nên chạy hai lần. Nó luôn kiểm tra (dành một chút thời gian) và cập nhật 'trống' và tiếp tục. Tuy nhiên, chỉ trong trường hợp nếu bạn muốn loại bỏ điều đó và 'kiểm tra' trước khi nhập - điều này sẽ hoạt động (thay đổi phần tương tự ở trên) ...

var migrator = new DbMigrator(_configuration);
if (!context.Database.CompatibleWithModel(throwIfNoMetadata: false))
    if (migrator.GetPendingMigrations().Any())
        migrator.Update();

(đây là kiểm tra dư thừa / kiểm tra kỹ lưỡng - một trong những if-s phải là đủ. Hãy dừng lại ở đó - và xem chính xác điều gì đang xảy ra, nó sẽ không xâm nhập - sau khi Db được di chuyển. Như tôi đã đề cập, hoạt động tốt khi tôi kiểm tra nó.

CHỈNH SỬA:

Thay thế bên trong của InitializeDatabase với ...

var doseed = !context.Database.Exists();
// && new DatabaseTableChecker().AnyModelTableExists(context);
// check to see if to seed - we 'lack' the 'AnyModelTableExists' - could be copied/done otherwise if needed...

var migrator = new DbMigrator(_configuration);
// if (doseed || !context.Database.CompatibleWithModel(throwIfNoMetadata: false))
    if (migrator.GetPendingMigrations().Any())
        migrator.Update();

// move on with the 'CreateDatabaseIfNotExists' for the 'Seed'
base.InitializeDatabase(context);
if (doseed)
{
    Seed(context);
    context.SaveChanges();
}

Điều này hoạt động xung quanh (một nửa chặng đường) không gieo - nếu quá trình di chuyển diễn ra trước. Và việc di chuyển phải là người đầu tiên, nếu không bạn sẽ gặp vấn đề.

Bạn vẫn cần phải thực hiện đúng cách - đây là ý chính nếu không phải là tất cả những gì bạn có thể cần - nhưng nếu có bất kỳ vấn đề nào với w / MySQL, v.v., có thể một số công việc khác ở đây.

Lưu ý: Vẫn seeding không gọi nếu bạn có db, nhưng nó trống. Vấn đề là trộn hai trình khởi tạo khác nhau. Vì vậy, bạn sẽ phải giải quyết vấn đề đó - bằng cách triển khai những gì Create ... thực hiện bên trong (lệnh gọi mà chúng tôi không thể gọi) hoặc một cái gì đó khác.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. LOAD DATA LOCAL INFILE đưa ra lỗi Lệnh đã sử dụng không được phép với phiên bản MySQL này

  2. Cách kết nối với cơ sở dữ liệu MySQL

  3. Mệnh đề tương đương CHỈ TRONG () MySQL

  4. MySQL NOT IN truy vấn

  5. Chọn bằng cách sử dụng tên bảng được tạo động