2013-06-10 35 views
10

Với Migration sau:FluentMigrator quay trở lại cột Không gọn gàng?

[Migration(1)] 
public class Mig001 : Migration 
{ 
    public override void Up() 
    { 
     Alter.Table("foo").AlterColumn("bar").AsInt32().Nullable(); 
    } 

    public override void Down() 
    { 
     Alter.Table("foo").AlterColumn("bar").AsInt32().NotNullable(); 
    } 
} 

Các migrator làm thay đổi một cột và làm cho nó nullable và trên rollback nó ngược lại và làm cho nó không nullable một lần nữa.

Cho phép dữ liệu nói đã được thêm vào foo kể từ khi di chuyển; hiện có các hàng có null trong cột bar.

Nếu nó được khôi phục thì thao tác sẽ không thành công, có cách nào trong trình xử lý thông thạo để xử lý trường hợp này không? Hoặc thực hành tốt nhất là gì.

Trả lời

10

Câu trả lời ngắn gọn là đặt giá trị mặc định cho tất cả các cột có giá trị nullable. Bạn có thể làm điều này chỉ với sql bằng cách sử dụng biểu thức Execute.Sql. Điều này phải trước biểu thức Alter.Table.

public override void Down() 
{ 
    Execute.Sql("update foo set bar = 0 where bar is null"); 
    Alter.Table("foo").AlterColumn("bar").AsInt32().NotNullable(); 
} 

Câu trả lời dài gọn là bạn luôn đảm bảo rằng bạn có thể khôi phục di chuyển và bạn có chắc chắn bạn cần thực hiện điều đó không?

Ví dụ: nếu hành động lên là tạo bảng và hành động giảm là thả bảng, bạn có nên lưu dữ liệu trong bảng tạm thời để nó không biến mất không? Đối với hầu hết các trường hợp sử dụng, hành động giảm được sử dụng khi triển khai trong môi trường thử nghiệm hoặc khi quay trở lại quá trình triển khai không thành công và rất hiếm khi bạn quay lại quá trình di chuyển sau khi được triển khai.

+0

tôi đoán rằng sẽ không hoạt động nếu 'bar' là một cột khóa ngoại? Phương thức Down có thể để trống không? – user1838662

+0

Nếu đó là cột khóa ngoài thì truy vấn sql sẽ phải thông minh hơn một chút và tìm giá trị đúng để đặt. Hay bạn có một giá trị khóa ngoài mà sẽ hoạt động như một giá trị mặc định? –

+0

Rất tiếc, không có giá trị khóa ngoại mặc định. '0' Sẽ trỏ đến một bản ghi trong bảng cha không tồn tại. – user1838662

6

Dưới đây là một cách thay thế để thực hiện di chuyển không yêu cầu thực thi SQL trực tiếp.

public override void Down() 
{ 
    Update.Table("foo").Set(new { bar = 0 }).Where(new { bar = (int?) null }); 
    Alter.Table("foo").AlterColumn("bar").AsInt32().NotNullable(); 
} 
0

Cũ chủ đề nhưng bạn có thể làm điều này để cung cấp cho các hàng hiện có một (mới) giá trị:

  migration.Alter.Table("foo") 
       .AlterColumn("bar") 
       .AsDateTime() 
       .NotNullable() 
       .SetExistingRowsTo(DateTime.UtcNow) 
      ; 
+1

nhưng hiện SetExistingRowsTo có thêm điều kiện 'bar là null' không? Hoặc nó sử dụng tất cả các hàng ... – Serg046

+0

SetExistingRowsTo sẽ đặt * tất cả * các hàng hiện có, vì mục đích của nó là tạo thêm các cột không rỗng không đơn giản mặc định. Chúng tôi cần thêm một trình trợ giúp như SetNullRowsTo hoặc thứ gì đó của ilk, nhưng thành thật mà nói, trong trường hợp cập nhật một cột hiện có từ null thành null, tôi nghĩ sử dụng phương pháp được gợi ý bởi Lucas là phương pháp tốt nhất và không kết quả làm tắc nghẽn api với các phương thức trợ giúp giả mạo. – Mike

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