某些 EF Core Tools 命令(例如 Migrations 命令)需要在設計時期建立衍生 DbContext 實例,才能收集應用程式實體類型的詳細資訊,以及它們如何對應至資料庫架構。 在大部分情況下,DbContext 的配置最好是類似於 運行時間的配置方式。
工具有多種方式嘗試創造 DbContext。 如果找到 an IDesignTimeDbContextFactory<TContext> ,工具會用它代替其他創建模式。 設計時工廠是獨立 遷移專案 及啟動專案為特定平台的應用程式的推薦模式。
從應用程式服務
如果您的啟動專案使用 ASP.NET Core Web 主機 或 .NET Core 泛型主機,這些工具會嘗試從應用程式的服務提供者取得 DbContext 物件。
先嘗試透過叫用 Program.CreateHostBuilder() 和呼叫 Build() 來取得服務提供者,然後存取Services屬性。
public class Program
{
public static void Main(string[] args)
=> CreateHostBuilder(args).Build().Run();
// EF Core uses this method at design time to access the DbContext
public static IHostBuilder CreateHostBuilder(string[] args)
=> Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(
webBuilder => webBuilder.UseStartup<Startup>());
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
=> services.AddDbContext<ApplicationDbContext>();
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
}
}
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
Note
當您建立新的 ASP.NET Core 應用程式時,預設會包含此勾點。
DbContext 本身及其建構函式中的任何相依性,都必須在應用程式的服務提供者中註冊為服務。 可以藉由在
使用不含參數的建構函式
如果無法從應用程式服務提供者取得 DbContext,工具會尋找專案內的衍生 DbContext 類型。 然後,他們會嘗試使用不含參數的建構函式來建立實例。 如果使用 DbContext 方法設定,則這可以是預設建構函式 OnConfiguring。
從設計時期工廠
您也可以藉由實作Microsoft.EntityFrameworkCore.Design.IDesignTimeDbContextFactory<TContext>介面來告訴工具如何建立DbContext:如果在與衍生DbContext相同的專案中,或者在應用程式啟動專案中找到實作此介面的類別,工具會略過建立DbContext的其他方式,而改用設計時期工廠。
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);
}
}
如果上下文建構器有未登錄在 DI 中的相依關係,或你沒有使用 DI,或應用程式啟動專案無法被工具執行,設計時工廠尤其有用。
在設計時配置與應用程式執行時相同的提供者、模型選項及遷移組件。 否則,工具可以為與應用程式所用模型不同的模型進行支架遷移。 不要假設有可選的命令列參數;驗證參數並提供合適的開發預設或設定來源。
Args
IDesignTimeDbContextFactory<TContext>.CreateDbContext和Program.CreateHostBuilder都接受命令列參數。
您可以從工具指定這些自變數:
dotnet ef database update -- --environment Production
令牌 -- 會指示 dotnet ef 將後續的所有項目視為自變數,而不是嘗試將它們剖析為選項。 未使用 dotnet ef 的任何額外自變數會轉送至應用程式。