2012-02-18 27 views
41

Tôi đã sử dụng Entity Framework 4.3 trên cơ sở dữ liệu hiện có và tôi có một vài kịch bản mà tôi đang cố gắng phục vụ.Cách tốt nhất để gia tăng dữ liệu hạt nhân trong Entity Framework 4.3

Thứ nhất, nếu tôi xóa cơ sở dữ liệu của mình, tôi muốn EF tạo lại nếu từ đầu - tôi đã sử dụng thành công trình khởi tạo cơ sở dữ liệu CreateDatabaseIfNotExists cho việc này. Thứ hai, nếu tôi cập nhật mô hình của mình và cơ sở dữ liệu đã tồn tại, tôi muốn cơ sở dữ liệu được cập nhật tự động - tôi đã sử dụng thành công Entity Framework 4.3 Migrations cho việc này.

Vì vậy, đây là câu hỏi của tôi. Giả sử tôi thêm một bảng mới vào mô hình của tôi yêu cầu một số dữ liệu tham chiếu, cách tốt nhất để đảm bảo rằng dữ liệu này được tạo ra khi trình intialiser của cơ sở dữ liệu chạy và khi di chuyển chạy. Mong muốn của tôi là dữ liệu được tạo khi tôi tạo db từ đầu và khi cơ sở dữ liệu được cập nhật do kết quả của quá trình di chuyển đang chạy. Trong một số ví dụ về di cư EF, tôi đã thấy mọi người sử dụng hàm SQL() trong phương thức UP để di chuyển dữ liệu hạt giống, nhưng nếu có thể tôi sẽ sử dụng ngữ cảnh để tạo dữ liệu hạt giống (như bạn thấy trong hầu hết ví dụ khởi tạo cơ sở dữ liệu) vì có vẻ lạ với tôi rằng bạn sẽ sử dụng sql thuần túy khi toàn bộ ý tưởng của EF đang trừu tượng hóa nó. Tôi đã cố gắng sử dụng ngữ cảnh trong phương thức UP nhưng vì lý do nào đó, nó không nghĩ rằng một bảng đã được tạo trong quá trình di chuyển tồn tại khi tôi cố thêm dữ liệu hạt giống ngay bên dưới cuộc gọi để tạo bảng.

Bất kỳ sự khôn ngoan nào được đánh giá cao.

Trả lời

53

Nếu bạn muốn sử dụng các thực thể để lấy dữ liệu, bạn nên sử dụng phương pháp Seed trong cấu hình di chuyển của mình. Nếu bạn tạo dự án mới Enable-Migrations bạn sẽ nhận được lớp cấu hình này:

internal sealed class Configuration : DbMigrationsConfiguration<YourContext> 
{ 
    public Configuration() 
    { 
     AutomaticMigrationsEnabled = false; 
    } 

    protected override void Seed(CFMigrationsWithNoMagic.BlogContext context) 
    { 
     // This method will be called after migrating to the latest version. 

     // You can use the DbSet<T>.AddOrUpdate() helper extension method 
     // to avoid creating duplicate seed data. E.g. 
     // 
     // context.People.AddOrUpdate(
     //  p => p.FullName, 
     //  new Person { FullName = "Andrew Peters" }, 
     //  new Person { FullName = "Brice Lambson" }, 
     //  new Person { FullName = "Rowan Miller" } 
     // ); 
     // 
    } 
} 

Cách cách dữ liệu di cư khởi đầu không rất hiệu quả vì nó là vụ phải được sử dụng cho một số hạt giống rất cơ bản. Mọi cập nhật cho phiên bản mới sẽ trải qua toàn bộ tập hợp và cố gắng cập nhật dữ liệu hiện có hoặc chèn dữ liệu mới. Nếu bạn không sử dụng phương pháp mở rộng AddOrUpdate, bạn phải tự bảo đảm rằng dữ liệu được đưa vào cơ sở dữ liệu chỉ khi chúng chưa xuất hiện.

Nếu bạn muốn cách hiệu quả cho hạt giống bởi vì bạn phải gieo rắc o rất nhiều dữ liệu bạn sẽ nhận được kết quả tốt hơn với điểm chung:

public partial class SomeMigration : DbMigration 
{ 
    public override void Up() 
    { 
     ... 
     Sql("UPDATE ..."); 
     Sql("INSERT ..."); 
    } 

    public override void Down() 
    { 
     ... 
    } 
} 
+8

Bạn thực sự có thể tạo ngữ cảnh trong phương thức Up và sử dụng AddOrUpdate để chèn hàng. Tuy nhiên, điều này sẽ không được gói trong giao dịch di chuyển để có thể gây ra sự cố. Ngoài ra nó không được đảm bảo để biên dịch trong tương lai khi mô hình thay đổi. – Betty

+0

Tôi đã thử tạo một ngữ cảnh trong phương thức Up, nhưng nó đã ném một lỗi nói rằng bảng không tồn tại. Tôi sẽ thử SQL trong phương thức "Up" thay thế. –

+8

@Ladislav độ sâu kiến ​​thức của bạn về EF tiếp tục làm tôi ngạc nhiên, bạn đã xem xét việc tạo ra một cuốn sách về chủ đề và có lẽ giải quyết những hiểu lầm phổ biến mà bạn gặp phải ở đây? – kingdango

32

tôi sẽ không khuyên bạn sử dụng Sql() cuộc gọi trong phương pháp Up() của bạn bởi vì (IMO) điều này thực sự dành cho mã di chuyển thực tế mà không có hàm dựng sẵn, thay vì mã hạt giống.

Tôi thích nghĩ về dữ liệu hạt giống như một thứ có thể thay đổi trong tương lai (ngay cả khi lược đồ của tôi không), vì vậy tôi chỉ viết các kiểm tra "phòng thủ" xung quanh tất cả các chèn của tôi trong hàm hạt giống để đảm bảo rằng hoạt động đã không cháy trước đó.

Hãy xem xét một kịch bản trong đó bạn có bảng "Loại" bắt đầu bằng 3 mục nhập, nhưng sau đó bạn thêm một thứ 4. Bạn không nên cần "di chuyển" để giải quyết vấn đề này.

Sử dụng Seed() cũng cung cấp cho bạn ngữ cảnh đầy đủ để làm việc, điều này đẹp hơn rất nhiều so với sử dụng các chuỗi sql đơn giản theo phương pháp Sql() mà Ladislav đã trình bày.Ngoài ra, hãy nhớ rằng lợi ích của việc sử dụng các phương pháp EF tích hợp cho cả mã di trú và mã hạt giống là các hoạt động cơ sở dữ liệu của bạn vẫn là nền tảng trung lập. Điều này có nghĩa là các thay đổi và truy vấn lược đồ của bạn có thể chạy trên Oracle, Postgre, v.v. Nếu bạn viết SQL thô thực tế thì bạn có khả năng tự khóa mình một cách không cần thiết.

Bạn có thể ít quan tâm hơn về điều này vì 90% người dùng EF sẽ chỉ truy cập SQL Server, nhưng tôi chỉ ném nó ra ngoài để cung cấp cho bạn một quan điểm khác về giải pháp.

+7

Tôi nghĩ rằng phương pháp "Up" là một nơi tốt để làm dữ liệu "Tham khảo" - dữ liệu tham chiếu thường ngụ ý rằng ứng dụng cần dữ liệu đó cho một số loại logic. – nootn

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