Tôi làm cách nào để vô hiệu hóa các lần di chuyển đầu tiên của mã


85

Tôi có một mô hình thực thể đầu tiên mã trong EF5. Nhưng tôi muốn quản lý các thay đổi trong cơ sở dữ liệu theo cách thủ công - tôi không muốn EF sửa đổi cơ sở dữ liệu hiện có của tôi và tất cả dữ liệu của nó. Nhưng khi tôi thực hiện các thay đổi song song trong ánh xạ EF và trong cơ sở dữ liệu, EF từ chối hoạt động bình thường và nói với tôi rằng tôi cần sử dụng di chuyển mã trước. Làm cách nào để tắt tính năng này?


Câu trả lời:


100

đặt Database.SetInitializer thành null.

public class DatabaseContext: DbContext
{
    //the base accepts the name of the connection string provided in the web.config as a parameter
    public DatabaseContext()
        : base("DatabaseContext")
    {
        //disable initializer
        Database.SetInitializer<DatabaseContext>(null);
    }

2
Đặt bộ khởi tạo trên phương thức khởi tạo cá thể của ngữ cảnh không có ý nghĩa. EF sẽ gọi trình khởi tạo trước khi thực sự nhận được mã đó nếu bạn cố gắng tạo một ngữ cảnh mới.
Jcl

1
Chỉ cần xác minh câu trả lời bằng cách xem "Công cụ chẩn đoán" trong VS 2017. Các lệnh gọi ADO.NET trước khi truy vấn SQL mong muốn đầu tiên đã dừng lại sau khi đặt intializer thành null trong hàm tạo.
Karl

2
Nó hoạt động như mong đợi. Đúng là EF sẽ gọi bộ khởi tạo trước đó, nhưng sau đó gọi lại nó bên trong hàm tạo làm cho DbContext chỉ bỏ qua các lần di chuyển, trong trường hợp bạn muốn bỏ qua thực tế là bạn __MigrationHistorykhông có lần di chuyển mới nhất và bạn không muốn không lam gi cả. Trong trường hợp của tôi, tôi sử dụng di chuyển trong môi trường nhà phát triển, nhưng khi triển khai sang phiên bản sản xuất, tôi sử dụng SSDT để cập nhật cơ sở dữ liệu. Do đó, EF sẽ phàn nàn rằng mô hình đã thay đổi vì __MigrationHistorysẽ không có lần di chuyển mới nhất, nhưng tôi có thể đảm bảo rằng cơ sở dữ liệu đã được cập nhật.
Alisson

Tôi sẽ đề nghị chuyển lời gọi tới Database.SetInitializertừ hàm tạo sang hàm tạo lớp. Điều đó đảm bảo cuộc gọi chỉ được thực hiện một lần.
Steven

40

Vì vậy, câu trả lời đầy đủ nhất mà tôi đã tìm thấy là:

  1. Xóa Migrationsthư mục bên trong dự án của bạn.
  2. Đặt Database.SetInitializer<DatabaseContext>(null);bên trong bộ khởi tạo DatabaseContext của bạn.
  3. Xóa bảng __MigrationHistorybên trong cơ sở dữ liệu của bạn. Đối với EF6 +, bảng nằm dưới Tablesnhưng đối với các phiên bản trước đó, bảng nằm dưới System Tables.
  4. Xây dựng và chạy.
  5. Lợi nhuận.

Thật không may sau khi làm theo các bước này, EF6 vẫn kiểm tra sự tồn tại của __MigrationHistorymỗi lần khởi động ứng dụng của tôi, điều này làm tăng thêm vài mili giây vào thời gian khởi động ứng dụng của tôi. Có cách nào để vô hiệu hóa __MigrationHistoryhoàn toàn kiểm tra không?
Đại

27

Nếu bạn muốn tắt hoàn toàn tính năng di chuyển:

https://stackoverflow.com/a/9709407/141172

Tuy nhiên, tôi thấy tốt hơn nên giữ cho các lần di chuyển đầu tiên của mã được bật, nhưng sử dụng -Scripttùy chọn để EF tạo tập lệnh thay đổi DB cho tôi mà tôi có thể áp dụng cho từng cơ sở dữ liệu (phát triển, QA, Sản xuất) theo cách thủ công:

Update-Database -Script -ProjectName MyProject -StartupProjectName MyProject

Bằng cách đó, EF sẽ tạo tập lệnh thay đổi cho tôi và tôi vẫn có toàn quyền kiểm soát các thay đổi đang được áp dụng. Tôi phiên bản các tập lệnh thay đổi giống như bất kỳ mã nguồn nào khác.


1
liên kết của bạn không thực sự tương ứng với completely turn off migrations. Để làm điều đó: thêm Database.SetInitializer<YourContextType>(null)để khởi động các ứng dụng của bạn
Don Cheadle

Bất kỳ ý tưởng làm thế nào để đạt được điều này với EF Core?
Shimmy Weitzhandler

@Shimmy: EF Core không bao giờ được tự động cố gắng thay đổi cơ sở dữ liệu của bạn. Xem github.com/dotnet/efcore/issues/3152
Eric J.

26

Nếu bạn đã sử dụng Migrations thì chỉ thay đổi Bộ khởi tạo sẽ không hữu ích. Bạn cần vào Management Studio, mở các bảng cơ sở dữ liệu của mình, đi tới System Tablesthư mục và xóa __MigrationHistorybảng nằm ở đó (đối với EF6 trở lên, bảng nằm ngay bên dưới Tables). Điều này sẽ tắt Migrations cho tốt.


7
Bảng __MigrationHistory nằm ngay dưới Bảng, không phải Bảng hệ thống.
Peter Hedberg

6
@PeterHedberg Điều này đúng với EF6 +. Đối với các phiên bản trước đó, nó nằm dưới System Tables.
Episodex

1
Bạn cũng có thể đổi tên bảng, thay vì xóa nó, bằng cách sử dụng sp_rename. Tôi cũng đã tắt trình khởi tạo.
NMrt

2

Tôi vừa giải quyết "vấn đề" này bằng cách

  1. Xóa bảng "_MigrationHistory" khỏi cơ sở dữ liệu.
  2. Xóa thư mục "Di chuyển" tạo thành dự án.
  3. Đang cập nhật tệp EDMX.
  4. Làm sạch dự án và xây dựng lại nó.

Cấu hình môi trường của tôi đang theo sau

1. Visual Studio 2017 15.8.2
2. ASP NET MVC project
3. .NET Framework 4.6.1
4. Entity Framework 6.2.0

Tôi có thể hỏi bạn đã cập nhật những gì trong tệp EDMX không? Tôi cũng đang sử dụng Cơ sở dữ liệu đầu tiên và nó vẫn đang truy vấn các Bảng di chuyển không tồn tại ... Cảm ơn!
dalcam

Điều gì sẽ xảy ra nếu sau này chúng ta cần di chuyển, nó có _MigrationHistorytự động tạo bảng mới không?
sairfan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.