2017-02-20 18 views
23

Ứng dụng của tôi đang được chuyển đến .NET core sẽ sử dụng EF Core mới với SQLite. Tôi muốn tự động tạo cơ sở dữ liệu và cấu trúc bảng khi ứng dụng được chạy lần đầu tiên. Theo tài liệu lõi EF này được thực hiện bằng thủ công lệnhtự động tạo cơ sở dữ liệu trong Entity Framework Core

dotnet ef migrations add MyFirstMigration 

dotnet ef database update 

Tuy nhiên tôi không muốn người dùng cuối để nhập các lệnh này và muốn có ứng dụng tạo và thiết lập cơ sở dữ liệu để sử dụng đầu tiên. Đối với EF 6, có chức năng như

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

Nhưng trong EF Core này dường như không tồn tại. Tôi không thể tìm thấy bất kỳ ví dụ hoặc tài liệu về một cái gì đó tương đương với lõi EF và nó không được đề cập trong danh sách các tính năng còn thiếu trong tài liệu lõi EF. Tôi đã thiết lập các lớp mô hình vì vậy tôi có thể viết một số mã để khởi tạo cơ sở dữ liệu dựa trên các mô hình nhưng sẽ dễ dàng hơn nếu khung làm việc này tự động. Tôi không muốn tự động xây dựng mô hình hoặc di chuyển, chỉ cần tạo cấu trúc bảng trên cơ sở dữ liệu mới.

Tôi có thiếu gì đó ở đây hoặc tự động tạo chức năng bảng bị thiếu trong lõi EF không?

Trả lời

22

Nếu bạn đã tạo di chuyển, bạn có thể thực hiện chúng trong Startup.cs như sau.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
     using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()) 
     { 
      var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); 
      context.Database.Migrate(); 
     } 

     ... 

Điều này sẽ tạo cơ sở dữ liệu và các bảng sử dụng di chuyển được thêm vào của bạn.

Nếu bạn không sử dụng Entity Framework Migrations, và thay vào đó chỉ cần mô hình DbContext bạn tạo ra chính xác như nó là trong lớp ngữ cảnh của bạn lúc chạy đầu tiên, sau đó bạn có thể sử dụng:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
     using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()) 
     { 
      var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); 
      context.Database.EnsureCreated(); 
     } 

     ... 

Thay vào đó.

Nếu bạn cần phải xoá bỏ cơ sở dữ liệu của bạn trước khi thực hiện chắc chắn nó được tạo ra, hãy gọi:

  context.Database.EnsureDeleted(); 

Ngay trước khi bạn gọi EnsureCreated()

Phỏng theo: http://docs.identityserver.io/en/release/quickstarts/8_entity_framework.html?highlight=entity

+0

Tôi vẫn khá mới với EF, tôi đã tạo ra các lớp xác định cấu trúc dữ liệu bằng cách sử dụng mã EF 6 đầu tiên "tạo từ cơ sở dữ liệu" từ studio trực quan bằng cách sử dụng tệp cơ sở dữ liệu hiện tại. Sau đó tôi cắt/dán chúng vào giải pháp VS lõi dotnet mới - vì vậy tôi đoán đây không phải là di chuyển. Điều đó có nghĩa là tôi phải tạo một tệp di chuyển trước khi mã trên có thể được sử dụng? – deandob

+0

Tôi xin lỗi, tôi đã làm một sai lầm trong câu trả lời của tôi, nếu bạn không sử dụng di chuyển, có thể sử dụng lệnh context.Database.EnsureCreated()/EnsureDeleted(), chi tiết hơn trong https://blogs.msdn.microsoft. com/dotnet/2016/09/29/triển khai-seeding-custom-quy ước-và-interceptors-in-ef-core-1-0/ –

+0

Đúng, làm việc một điều trị, cảm ơn. – deandob

7

câu trả lời của tôi rất giống với câu trả lời của Ricardo, nhưng tôi cảm thấy rằng cách tiếp cận của tôi đơn giản hơn một chút đơn giản bởi vì có quá nhiều thứ đang diễn ra trong hàm using của tôi thậm chí không chắc chắn chính xác nó hoạt động như thế nào ở cấp độ thấp hơn.

Vì vậy, đối với những người muốn có một giải pháp đơn giản và sạch sẽ tạo ra một cơ sở dữ liệu cho bạn, nơi bạn biết chính xác những gì đang xảy ra dưới mui xe, đây là dành cho bạn:

public Startup(IHostingEnvironment env) 
{ 
    using (var client = new TargetsContext()) 
    { 
     client.Database.EnsureCreated(); 
    } 
} 

này khá nhiều có nghĩa là trong DbContext mà bạn đã tạo (trong trường hợp này, tên tôi là TargetsContext), bạn có thể sử dụng một phiên bản DbContext để đảm bảo rằng các bảng được xác định trong lớp được tạo khi Startup.cs chạy trong ứng dụng của bạn.

+2

Cũng giống như thông tin từ [ở đây] (https://github.com/aspnet/EntityFrameworkCore/issues/3160): 'EnsureCreated' hoàn toàn bỏ qua di chuyển và chỉ tạo lược đồ cho bạn, bạn không thể kết hợp điều này với di chuyển. 'EnsureCreated' được thiết kế để thử nghiệm hoặc tạo mẫu nhanh nơi bạn đồng ý với việc bỏ và tạo lại cơ sở dữ liệu mỗi lần. Nếu bạn đang sử dụng di chuyển và muốn chúng tự động được áp dụng khi bắt đầu ứng dụng, thì bạn có thể sử dụng 'context.Database.Migrate()' để thay thế. –

+0

@ThomasSchneiter Ồ, tuyệt! Cảm ơn vì điều đó! Tôi không ý kiến. –

+0

Điều này giải đáp sự nhầm lẫn của tôi tại sao chuỗi kết nối của tôi không hoạt động ... :( Vì vậy, cơ sở dữ liệu không được tự động tạo ra mà bạn phải chỉ định Database.EnsureCreated() mà tôi đã thực hiện trong bộ dựng DbContext của mình Cảm ơn bạn rất nhiều. từ 3 ​​ngày tiến thoái lưỡng nan. X_X – pampi

1

Nếu bạn chưa tạo di chuyển, có 2 tùy chọn

1.tạo cơ sở dữ liệu và các bảng từ ứng dụng chính:

var context = services.GetRequiredService<YourRepository>(); 
context.Database.EnsureCreated(); 

2.create bảng nếu cơ sở dữ liệu đã tồn tại:

var context = services.GetRequiredService<YourRepository>(); 
context.Database.EnsureCreated(); 
RelationalDatabaseCreator databaseCreator = 
(RelationalDatabaseCreator)context.Database.GetService<IDatabaseCreator>(); 
databaseCreator.CreateTables(); 

Nhờ Bubi của answer

2

Nếu bạn nhận được bối cảnh thông qua các tham số danh sách Cấu hình trong Startup.cs, thay vào đó bạn có thể thực hiện việc này:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, LoggerFactory loggerFactory, 
    ApplicationDbContext context) 
{ 
     context.Database.Migrate(); 
     ... 
Các vấn đề liên quan