2011-03-15 29 views
5

Gói EF mới nhất NuGet đầu tiên đi kèm với triển khai tùy chỉnh IDatabaseInitializer được gọi là DontDropDbJustCreateTablesIfModelChanged. Như tên của nó, khi một thay đổi mô hình được phát hiện, nó sẽ không thả và tạo lại toàn bộ cơ sở dữ liệu, chỉ cần thả và tạo lại các bảng.Chiến lược khởi tạo tùy chỉnh cho mã EF Đầu tiên không thả bảng để thêm cột

Nói rằng tôi có lớp mô hình này:

public class User 
{ 
    public string Username { get; set; } 

    // This property is new; the model has changed! 
    public string OpenID { get; set; } 
} 

Làm thế nào người ta sẽ đi về thực hiện một IDatabaseInitializer rằng không thả bất kỳ bảng hoặc. Trong trường hợp này, nó sẽ chỉ thêm một cột OpenID vào bảng Người dùng?

Trả lời

5

Tôi nghĩ đó là vấn đề của SQL. Vì vậy, đối với SQL Server, bạn có thể viết một cái gì đó như:

public class MyInitializer : IDatabaseInitializer<MyContext> 
{ 
    public void InitializeDatabase(MyContext context) 
    { 
     context.Database.SqlCommand(
      @" 
      IF NOT EXISTS (SELECT 1 FROM sys.columns AS col 
          INNER JOIN sys.tables AS tab ON tab.object_Id = col.object_Id 
          WHERE tab.Name = 'User' AND col.Name = 'OpenId') 
      BEGIN 
       ALTER TABLE dbo.User ADD OpenId INT; 
      END"); 
    } 
} 

Nhưng theo cùng cách bạn có thể thực thi tập lệnh đó mà không cần thêm vào ứng dụng mà tôi nghĩ là cách tiếp cận tốt hơn.

+0

Có, đó là một cuộc tấn công tò mò, xem cách tất cả các triển khai IDatabaseInitializer sẵn có đã chọn phương pháp "phá hoại" :) Cảm ơn –

+0

@Sergi Papaseit: Điều này rất thú vị. Bạn có tiếp tục không? Một trong những điều mà tôi muốn được thực hiện vào EF 4.1 Code đầu tiên là chuyển đổi cơ sở dữ liệu. Tôi tin rằng những gì đã được trình bày bởi Ladislav ở trên có thể thực sự hoạt động nếu nó được xây dựng trên và bằng cách nào đó tự động. Vì vậy, nếu bạn đã đi xa hơn vào điều này, xin vui lòng chia sẻ nó với chúng tôi :) – Kassem

+0

@ Kassem - Tôi đã không thực sự. Một người nào đó đã tạo ra một điểm rất tốt cho tôi ở đây trên SO, nói rằng điều này tất nhiên chỉ dành cho môi trường phát triển, vì vậy không cần phải để cho db bị mất mỗi lần ... Làm cho tôi biết nếu bạn làm vậy! ;) –

2

Với phiên bản Code First hiện tại, bạn không thể sửa đổi giản đồ của mình và giữ lại bất kỳ dữ liệu nào bạn có thể có trong bảng của mình. Nếu duy trì dữ liệu, chẳng hạn như dữ liệu tham khảo/bảng tra cứu là rất quan trọng với phiên bản này bạn có thể tạo Initializer của riêng bạn và ghi đè lên các phương pháp Seed để cư bảng của bạn

public class MyDbInitializer : DropCreateDatabaseIfModelChanges<MyContext> 
{ 
    protected override void Seed(MyContext context) 
    { 
     var countries = new List<Country> 
     { 
      new Country {Id=1, Name="United Kingdom"}, 
      new Country{Id=2, Name="Ireland"} 
     }; 

     countries.ForEach(c => context.Countries.Add(c)); 
    } 
} 

Và sau đó sử dụng này trong Application_Start của bạn:

Database.SetInitializer<MyContext>(new MyDbInitializer()); 

Tôi tin rằng điều này đang được giải quyết hiện tại bởi Nhóm EF, nhưng chưa sẵn sàng để phát hành tại thời điểm thả Code đầu tiên. Bạn có thể xem bản xem trước tại đây: Code First Migrations

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