Entity Framework Core配置DbContext的兩種方式
使用Entity Framework遷移過程中遇到過一個問題,在這里拿出來曬曬。
Unable to create an object of type 'xxxContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
要解決這個問題,就是我下面要闡述的內容了。
1. DbContext的兩種配置方式
我們先來看看DbContext的兩個構造函數:
protected DbContext();
public DbContext([NotNullAttribute] DbContextOptions options);
還有DbContext的兩個重寫方法:
protected internal virtual void OnConfiguring(DbContextOptionsBuilder optionsBuilder);
protected internal virtual void OnModelCreating(ModelBuilder modelBuilder);
根據錯誤提示,在微軟的官方文檔中,我們知道了配置DbContext有兩種方式:
-
使用無參構造函數,必須重寫
OnConfiguring()
函數public class BloggingContext : DbContext { public DbSet<Blog> Blogs { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseSqlite("Data Source=blog.db"); }
這樣使用的話,應用程序可以簡單地實例化此類上下文,而無需將任何內容傳遞給構造函數:
using (var context = new BloggingContext()) { // do stuff }
-
使用有參構造函數,無需重寫
OnConfiguring()
函數public class BloggingContext : DbContext { public BloggingContext(DbContextOptions<BloggingContext> options) : base(options) { } public DbSet<Blog> Blogs { get; set; } }
這樣使用的話,應用程序現在可以在實例化上下文時傳遞
DbContextOptions
,如下所示:var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>(); optionsBuilder.UseSqlite("Data Source=blog.db"); using (var context = new BloggingContext(optionsBuilder.Options)) { // do stuff }
2. 遷移過程中的工廠方法
那么按照官網的做法去寫的話,為什么還會出現文章最開頭的那個錯誤呢?這里我使用控制台和Asp.net core程序各創建了一次程序后,發現上述問題是我在使用控制台程序測試代碼時出現的,而Asp.net core程序卻沒有出現(具體的原理我還不清楚,希望各路大俠看到能幫助解答一下)。
這里說一下控制台程序出現此問題的解決辦法(微軟官方文檔):
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);
}
}
“可以通過實現接口來告訴工具如何創建 DbContext,通過創建類實現接口IDesignTimeDbContextFactory<TContext>
,如果實現此接口的類在與派生的項目相同的項目中或應用程序的啟動項目中找到,則這些工具將繞過創建 DbContext 的其他方法,並改用設計時工廠。”
問題便可迎刃而解。
3. 總結
以上解決方法僅針對控制台程序使用或測試Entity Framework時出現的問題,因為Asp.net程序按照官網給定的兩種方式去實現的話,不會出現這個問題。