Entity Framework Core配置DbContext的两种方式

。_饼干妹妹 提交于 2020-08-08 06:14:30

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程序按照官网给定的两种方式去实现的话,不会出现这个问题。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!