Làm cách nào để kích hoạt di chuyển EF cho nhiều ngữ cảnh để tách cơ sở dữ liệu?


122

Làm cách nào để kích hoạt di chuyển Entity Framework 5 (phiên bản 5.0.0) cho nhiều ngữ cảnh DB trong cùng một dự án, trong đó mỗi ngữ cảnh tương ứng với cơ sở dữ liệu riêng của nó? Khi tôi chạy Enable-Migrationstrong PM console (Visual Studio 2012), đã xảy ra lỗi vì có nhiều ngữ cảnh:

PM> Enable-Migrations
More than one context type was found in the assembly 'DatabaseService'.
To enable migrations for DatabaseService.Models.Product1DbContext, use Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContext.
To enable migrations for DatabaseService.Models.Product2DbContext, use Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContext.

Nếu tôi chạy, Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContexttôi không được phép chạy Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContextvì quá trình di chuyển đã tồn tại:Migrations have already been enabled in project 'DatabaseService'. To overwrite the existing migrations configuration, use the -Force parameter.


Câu trả lời:


126

Lần gọi thứ hai đến Enable-Migrations không thành công vì tệp Configuration.cs đã tồn tại. Nếu bạn đổi tên lớp và tệp đó, bạn sẽ có thể chạy Enable-Migrations thứ 2 đó, thao tác này sẽ tạo ra một Configuration.cs khác.

Sau đó, bạn sẽ cần chỉ định cấu hình bạn muốn sử dụng khi cập nhật cơ sở dữ liệu.

Update-Database -ConfigurationTypeName MyRenamedConfiguration

1
"MyRenameConfiguration" là gì?
Robert Noack

1
"MyRenameConfiguration" chỉ là văn bản giữ chỗ làm ví dụ. Bạn có thể đã đổi tên Configuration.cs ban đầu của mình thành bất kỳ thứ gì, (ví dụ: FooBar, sau đó chạy Update-Database -ConfigurationTypeName FooBar).
ckal

3
hình thức rút ngắn: Cập nhật cơ sở dữ liệu--conf MyRenamedConfiguration
Peter Kerr

100

Ngoài những gì @ckal đề xuất, điều quan trọng là cung cấp cho mỗi vùng tên riêng của Configuration.cs đã đổi tên. Nếu bạn không làm như vậy, EF sẽ cố gắng áp dụng các chuyển đổi vào ngữ cảnh sai.

Dưới đây là các bước cụ thể phù hợp với tôi.

Nếu Quá trình di chuyển bị lộn xộn và bạn muốn tạo một "đường cơ sở" mới:

  1. Xóa mọi tệp .cs hiện có trong thư mục Migrations
  2. Trong SSMS, hãy xóa bảng hệ thống __MigrationHistory.

Tạo quá trình di chuyển ban đầu:

  1. Trong Bảng điều khiển Trình quản lý Gói:

    Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextA
  2. Trong Solution Explorer: Đổi tên Migrations.Configuration.cs thành Migrations.ConfigurationA.cs. Điều này sẽ tự động đổi tên hàm tạo nếu sử dụng Visual Studio. Hãy chắc chắn rằng nó có. Chỉnh sửa cấu hìnhA.cs: Thay đổi không gian tên thành NamespaceOfContext.Migrations.MigrationsA

  3. Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextB -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextB
  4. Trong Solution Explorer: Đổi tên Migrations.Configuration.cs thành Migrations.ConfigurationB.cs. Một lần nữa, hãy đảm bảo rằng hàm tạo cũng được đổi tên thích hợp. Chỉnh sửa cấu hìnhB.cs: Thay đổi không gian tên thành NamespaceOfContext.Migrations.MigrationsB

  5. add-migration InitialBSchema -IgnoreChanges -ConfigurationTypeName
    ConfigurationB -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextB 
  6. Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB
  7. add-migration InitialSurveySchema -IgnoreChanges -ConfigurationTypeName
    ConfigurationA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName
    NameOfMainProject  -ConnectionStringName ContextA 
  8. Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

Các bước để tạo tập lệnh di chuyển trong Bảng điều khiển Trình quản lý Gói:

  1. Chạy lệnh

    Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

    hoặc là -

    Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB

    Có thể chạy lại lệnh này cho đến khi các thay đổi được áp dụng cho DB.

  2. Chạy các tập lệnh dựa trên cơ sở dữ liệu cục bộ mong muốn hoặc chạy Update-Database mà không có -Script để áp dụng cục bộ:

    Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

    hoặc là -

    Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB

# 4 thay đổi: Sửa ConfigurationA.cs -> Edit ConfigurationB.cs
Brian Rizo

1
@Biran: Cảm ơn vì đã chú ý điều đó. Tôi đã chỉnh sửa câu trả lời. Lưu ý, bạn cũng có thể tự chỉnh sửa câu trả lời. Vì bạn chưa có 2000 danh tiếng, câu trả lời của bạn cho hàng đợi đánh giá nhưng hàng đợi đó thường được thực hiện rất nhanh, vì vậy chỉnh sửa của bạn có thể đã được chấp thuận trong vòng vài phút.
Eric J.

5
CẢM ƠN BẠN! Đó là những gì tôi đã thiếu (không gian tên).
William M. Rawls

Điều này có thể hữu ích vì ban đầu tôi không hiểu rõ cách thực hiện đổi tên ở bước 2 và 4 : Khi bạn đổi tên tệp Configuration.cs thành ConfigurationA.cs hoặc ConfigurationB.cs, việc đổi tên cũng sẽ dẫn đến lớp và hàm tạo của nó cũng được đổi tên thành ConfigurationA hoặc ConfigurationB. Việc không đổi tên lớp sẽ gây ra thông báo lỗi khi bạn chạy lệnh add -igration - "Không tìm thấy kiểu cấu hình di chuyển 'ConfigurationA' trong assembly '...'" - và vâng, từ ngữ giống như rằng trong các thông báo lỗi mà tôi có trong VS2013 - LOL
Greg Barth

3
điều này đã giúp tôi! hoàn thành hướng dẫn với tất cả các tùy chọn và đặt hàng. đã tiết kiệm cho tôi nhiều giờ
elcool

82

Tôi vừa gặp phải vấn đề tương tự và tôi đã sử dụng giải pháp sau (tất cả từ Bảng điều khiển trình quản lý gói)

PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextA" -ContextTypeName MyProject.Models.ContextA
PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextB" -ContextTypeName MyProject.Models.ContextB

Thao tác này sẽ tạo ra 2 thư mục riêng biệt trong thư mục Migrations. Mỗi sẽ chứa Configuration.cstệp được tạo . Thật không may, bạn vẫn phải đổi tên các Configuration.cstệp đó nếu không sẽ có khiếu nại về việc có hai trong số chúng. Tôi đã đổi tên tệp của mình thành ConfigA.csConfigB.cs

CHỈNH SỬA : (Kevin McPheat lịch sự) Hãy nhớ khi đổi tên tệp Configuration.cs, hãy đổi tên lớp và hàm tạo / EDIT

Với cấu trúc này, bạn có thể đơn giản làm

PM> Add-Migration -ConfigurationTypeName ConfigA
PM> Add-Migration -ConfigurationTypeName ConfigB

Thao tác này sẽ tạo các tệp mã cho việc di chuyển bên trong thư mục bên cạnh tệp cấu hình (điều này thật tuyệt khi giữ các tệp đó lại với nhau)

PM> Update-Database -ConfigurationTypeName ConfigA
PM> Update-Database -ConfigurationTypeName ConfigB

Và cuối cùng nhưng không kém phần quan trọng, hai lệnh đó sẽ áp dụng các chuyển đổi chính xác cho cơ sở dữ liệu tương ứng của chúng.

CHỈNH SỬA ngày 08 tháng 2 năm 2016: Tôi đã thực hiện một thử nghiệm nhỏ với EF7 phiên bản 7.0.0-rc1-16348

Tôi không thể làm cho tùy chọn -o | --outputDir hoạt động. Nó tiếp tục choMicrosoft.Dnx.Runtime.Common.Commandline.CommandParsingException: Unrecognized command or argument

Tuy nhiên, có vẻ như lần đầu tiên một quá trình di chuyển được thêm, nó sẽ được thêm vào thư mục Migrations và một lần di chuyển tiếp theo cho một ngữ cảnh khác sẽ tự động được đưa vào một nhóm nhỏ các di chuyển.

Các tên ban đầu ContextAdường như vi phạm một số quy ước đặt tên nên bây giờ tôi sử dụng ContextAContextContextBContext. Sử dụng những tên này, bạn có thể sử dụng các lệnh sau: (lưu ý rằng dnx của tôi vẫn hoạt động từ bảng điều khiển trình quản lý gói và tôi không muốn mở một cửa sổ CMD riêng để thực hiện di chuyển)

PM> dnx ef migrations add Initial -c "ContextAContext"
PM> dnx ef migrations add Initial -c "ContextBContext"

Thao tác này sẽ tạo một ảnh chụp nhanh mô hình và lần di chuyển đầu tiên trong Migrationsthư mục cho ContextAContext. Nó sẽ tạo một thư mục có tên ContextBchứa các tệp này choContextBContext

Tôi đã thêm một ContextAthư mục theo cách thủ công và di chuyển các tệp di chuyển từ ContextAContextvào thư mục đó. Sau đó, tôi đổi tên không gian tên bên trong các tệp đó (tệp ảnh chụp nhanh, quá trình di chuyển ban đầu và lưu ý rằng có tệp thứ ba trong tệp di chuyển ban đầu ... Designer.cs). Tôi phải thêm .ContextAvào không gian tên, và từ đó khung xử lý tự động trở lại.

Sử dụng các lệnh sau sẽ tạo ra một sự di chuyển mới cho từng ngữ cảnh

PM>  dnx ef migrations add Update1 -c "ContextAContext"
PM>  dnx ef migrations add Update1 -c "ContextBContext"

và các tệp đã tạo được đặt vào đúng thư mục.


5
giải pháp tốt nhất, đơn giản và chúng tôi giữ một thư mục rõ ràng.
Malick

2
Đây là câu trả lời tôi cần. Không gian tên được thêm qua -MigrationsDirectory là câu trả lời! Cảm ơn bạn.
Crob

1
Giải pháp đẹp và sạch sẽ. Cảm ơn.
Stefan Cebulak

4
1,5 năm sau, tôi rất vui vì tôi có thể sử dụng bài đăng của chính mình để thiết lập một dự án mới.
bart s

1
Lưu ý khi bạn chạy add-migrationnó sẽ nhắc bạn Name. Điều này khiến tôi ConfigurationTypeNamehơi khó chịu vì tôi đã cung cấp và hơi khó chịu khi nó vừa nói Name:. Nhưng tất nhiên Tên nó muốn là mô tả 'con người có thể đọc được' về sự thay đổi - ví dụ. AddedProductshoặc IncreaseLengthOfNameFields. Trong thư mục Migrations, bạn sẽ nhận được điều này dưới dạng một phần của tên lớp để dễ dàng biết được là gì. Vì vậy, có hiệu lực Namegiống như một nhận xét đăng ký.
Simon_Weaver

7

Trong trường hợp bạn đã có một "Cấu hình" với nhiều lần di chuyển và muốn giữ nguyên lớp này, bạn luôn có thể tạo một lớp "Cấu hình" mới, đặt tên khác cho nó, chẳng hạn như

class MyNewContextConfiguration : DbMigrationsConfiguration<MyNewDbContext>
{
   ...
}

sau đó chỉ cần ra lệnh

Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName

và EF sẽ mở đầu cho việc di chuyển mà không gặp vấn đề gì. Cuối cùng cập nhật cơ sở dữ liệu của bạn, từ bây giờ, EF sẽ khiếu nại nếu bạn không cho anh ta biết bạn muốn cập nhật cấu hình nào:

Update-Database -ConfigurationTypeName MyNewContextConfiguration 

Làm xong.

Bạn không cần phải đối phó với Enable-Migrations vì nó sẽ phàn nàn rằng "Cấu hình" đã tồn tại và việc đổi tên lớp Cấu hình hiện có của bạn sẽ gây ra vấn đề cho lịch sử di chuyển.

Bạn có thể nhắm mục tiêu các cơ sở dữ liệu khác nhau hoặc cùng một cơ sở dữ liệu, tất cả các cấu hình sẽ dùng chung bảng __MigrationHistory.


4

Nếu có nhiều cơ sở dữ liệu hơn, hãy sử dụng các mã sau trong PowerShell

Add-Migration Starter -context EnrollmentAppContext 
  • 'Starter' là Tên di chuyển

  • 'EnrollmentAppContext' là tên của Ngữ cảnh ứng dụng của tôi

Bạn có thể mở PowerShell trong VS bằng cách thực hiện: Tools->NuGet Package Manager->Package Manager Console


1
Điều này đã giúp tôi. Cảm ơn! :)
noobprogrammer

3

Để cập nhật loại cơ sở dữ liệu sau các mã trong PowerShell ...

Update-Database -context EnrollmentAppContext

* nếu có nhiều cơ sở dữ liệu, chỉ sử dụng mã này, nếu không thì không cần thiết ..


0

EF 4.7 thực sự đưa ra một gợi ý khi bạn chạy Enable-migrations ở nhiều ngữ cảnh.

Đã tìm thấy nhiều loại ngữ cảnh trong assembly 'Service.Domain'.

To enable migrations for 'Service.Domain.DatabaseContext.Context1', 
use Enable-Migrations -ContextTypeName Service.Domain.DatabaseContext.Context1.
To enable migrations for 'Service.Domain.DatabaseContext.Context2',
use Enable-Migrations -ContextTypeName Service.Domain.DatabaseContext.Context2.
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.