設計階段 DbContext 建立Design-time DbContext Creation

某些 EF Core 工具命令 (例如,移轉命令) 需要衍生DbContext以收集應用程式的相關詳細資料,在設計階段建立的執行個體實體類型和它們如何對應到資料庫結構描述。Some of the EF Core Tools commands (for example, the Migrations commands) require a derived DbContext instance to be created at design time in order to gather details about the application's entity types and how they map to a database schema. 在大部分情況下,最好可DbContext藉此建立設定類似的方式,是它會如何設定在執行階段In most cases, it is desirable that the DbContext thereby created is configured in a similar way to how it would be configured at run time.

有的各種工具會嘗試建立DbContext:There are various ways the tools try to create the DbContext:

從應用程式服務From application services

如果您的啟始專案的 ASP.NET Core 應用程式,工具會嘗試從應用程式的服務提供者取得 DbContext 物件。If your startup project is an ASP.NET Core app, the tools try to obtain the DbContext object from the application's service provider.

工具會先嘗試叫用來取得服務提供者Program.BuildWebHost(),並存取IWebHost.Services屬性。The tools first try to obtain the service provider by invoking Program.BuildWebHost() and accessing the IWebHost.Services property.

注意

當您建立新的 ASP.NET Core 2.0 應用程式時,預設會包含此攔截程序。When you create a new ASP.NET Core 2.0 application, this hook is included by default. 在舊版的 EF Core 與 ASP.NET Core,工具會嘗試叫用Startup.ConfigureServices直接為了取得應用程式的服務提供者,但這個模式無法再正常運作中 ASP.NET Core 2.0 應用程式。In previous versions of EF Core and ASP.NET Core, the tools try to invoke Startup.ConfigureServices directly in order to obtain the application's service provider, but this pattern no longer works correctly in ASP.NET Core 2.0 applications. 如果您要升級為 2.0 的 ASP.NET Core 1.x 應用程式,您可以修改您Program類別,以符合新模式If you are upgrading an ASP.NET Core 1.x application to 2.0, you can modify your Program class to follow the new pattern.

DbContext本身和其建構函式中的任何相依性必須註冊為應用程式的服務提供者中的服務。The DbContext itself and any dependencies in its constructor need to be registered as services in the application's service provider. 這可以輕鬆地讓達成建構函式DbContext採用的執行個體DbContextOptions<TContext>做為引數並使用AddDbContext<TContext>方法.This can be easily achieved by having a constructor on the DbContext that takes an instance of DbContextOptions<TContext> as an argument and using the AddDbContext<TContext> method.

使用不含參數的建構函式Using a constructor with no parameters

如果無法從應用程式服務提供者取得 DbContext,這些工具尋找衍生DbContext專案內的型別。If the DbContext can't be obtained from the application service provider, the tools look for the derived DbContext type inside the project. 然後嘗試建立使用不含參數的建構函式的執行個體。Then they try to create an instance using a constructor with no parameters. 如果這是預設建構函式DbContext設定時,使用[ OnConfiguring ] 6方法。This can be the default constructor if the DbContext is configured using the OnConfiguring method.

從設計階段處理站From a design-time factory

您也可以告訴工具如何藉由實作來建立您的 DbContextIDesignTimeDbContextFactory<TContext>介面: 如果實作此介面的類別將找到在相同的專案衍生的DbContext或在應用程式的啟始專案,這些工具略過改為建立 DbContext 和使用的設計階段處理站的其他方法。You can also tell the tools how to create your DbContext by implementing the IDesignTimeDbContextFactory<TContext> interface: If a class implementing this interface is found in either the same project as the derived DbContext or in the application's startup project, the tools bypass the other ways of creating the DbContext and use the design-time factory instead.

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace MyProject
{
    public class BloggingContextFactory : IDesignTimeDbContextFactory<BloggingContext>
    {
        public BloggingContext CreateDbContext(string[] args)
        {
            var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
            optionsBuilder.UseSqlite("Data Source=blog.db");

            return new BloggingContext(optionsBuilder.Options);
        }
    }
}

注意

args參數是目前未使用。The args parameter is currently unused. 沒有問題追蹤指定的設計階段引數,從工具的能力。There is an issue tracking the ability to specify design-time arguments from the tools.

設計階段處理站可以是特別有用,如果您要以不同的方式設定的設計階段和執行階段的 DbContext,如果DbContext建構函式會採用額外的參數不在中註冊 DI,如果您未使用 DI,或者某些原因不想已BuildWebHost方法在 ASP.NET Core 應用程式的Main類別。A design-time factory can be especially useful if you need to configure the DbContext differently for design time than at run time, if the DbContext constructor takes additional parameters are not registered in DI, if you are not using DI at all, or if for some reason you prefer not to have a BuildWebHost method in your ASP.NET Core application's Main class.