在Asp.netCore中执行get方法时,该DbContext未配置任何数据库提供程序。

3

我使用Asp.net core创建了一个Web API项目,并添加了一个API控制器(名称为BlogController),在博客控制器中我有一个获取方法GetAllBlog,这是我的控制器:

[Route("api/[controller]")]
public class BlogController : Controller
{
    private static Logger logger = LogManager.GetCurrentClassLogger();

    public IContext _context { get; set; }
    public BlogController(IContext ctx)
    {
        _context = ctx;
    }

    [HttpGet]
    public IEnumerable<Blog> GetAllBlog()
    {
        return _context.Blogs.ToList();
    }
 }

这是我的IContext和模型:
public interface IContext : IDisposable
{
    DbSet<Blog> Blogs { get; set; }
    DbSet<Post> Posts { get; set; }
    int SaveChanges();
}

并且上下文:

public class Context : DbContext, IContext
{
    public Context(DbContextOptions<Context> options) : base(options)
    { }
    public virtual DbSet<Blog> Blogs { get; set; }
    public virtual DbSet<Post> Posts { get; set; }
}

以及模型:

public class Blog
{
    public int BlogId { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
    public DateTime? CreationDate { get; set; }
    public virtual IList<Post> Posts { get; set; }
}

当我调用GetAllBlog()时,出现了以下错误:

没有为此DbContext配置数据库提供程序。可以通过覆盖DbContext.OnConfiguring方法或在应用程序服务提供程序上使用AddDbContext来配置提供程序。如果使用了AddDbContext,则还要确保您的DbContext类型在其构造函数中接受一个DbContextOptions对象,并将其传递给DbContext的基础构造函数。问题出在哪里?

更新:这是Startup类中的ConfigurationService方法:
public void ConfigureServices(IServiceCollection services)
{
    var connection = @"Data Source=.;Initial Catalog=RestfullServices;Integrated Security=true";
    services.AddDbContext<Context>(options => options.UseSqlServer(connection));
    services.AddScoped<IContext>(p => new Context(new DbContextOptions<Context>()));
    services.AddApplicationInsightsTelemetry(Configuration);
    services.AddMvc();
}

1
你还应该展示添加数据库上下文的配置。 - Nkosi
1
你如何在IoC中映射IContext,应该放在哪里呢?你能发一下代码吗? - federico scamuzzi
与添加IContext到IoC时创建新选项有关。 - Nkosi
@Nkosi你的意思是什么?你能解释一下吗? - pejman
好的,在我开始之前,让我们试一下。尝试使用 services.AddScoped<IContext, Context>(); 看看是否有效。 - Nkosi
@Nkosi,它有效,请添加更多解释为什么会发生这种情况,以便标记为答案。 - pejman
1个回答

2

当配置 DbContext 时

services.AddDbContext<Context>(options => options.UseSqlServer(connection));

你可以配置它以使用特定选项options.UseSqlServer(connection)

但是当配置作用域上下文抽象时

services.AddScoped<IContext>(p => new Context(new DbContextOptions<Context>()));

正在创建一个新的Context,其配置与之前配置完全不同。

通过在启动期间更改如下方式注册IContext到 DI 框架中:

services.AddScoped<IContext, Context>();

DI框架将在创建Context实例时使用AddDbContext配置,该配置将具有从启动配置中要使用的选项,以便在创建DbContext实例时使用。 Startup.ConfigureServices最终会看起来像这样...
public void ConfigureServices(IServiceCollection services) {
    var connection = @"Data Source=.;Initial Catalog=RestfullServices;Integrated Security=true";
    services.AddDbContext<Context>(options => options.UseSqlServer(connection));
    services.AddScoped<IContext, Context>();
    services.AddApplicationInsightsTelemetry(Configuration);
    services.AddMvc();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接