简体   繁体   中英

Configure ASP.NET Core with Entity Framework: “No database provider has been configured for this DbContext”

I am trying to inject a simple connection string in an ASP.NET Core 2.1 API project.

appsettings.json:

{
    "ConnectionStrings": {
        "DefaultConnection": "Server=xxx.database.windows.net;Database=xxx;User Id=frontend;Password=xxx;"
    }
}

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    var connStr = Configuration.GetConnectionString("DefaultConnection");
    services.AddDbContext<DB>(options => options.UseSqlServer(connStr));

DbContext:

public class DB : DbContext
{
    public DB(DbContextOptions<DbContext> options) : base(options) { }
    public DB() { }

    public DbSet<MenuItem> MenuItemList { get; set; }
}

My Controller:

public class MenuItemsController : ControllerBase
{
    DB _context;
    public MenuItemsController(DB context)
    {
        _context = context;
    }

    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        try
        {
            var ddd = _context.MenuItemList.ToList();
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        return new string[] { "value1", "value2" };
    }
}

I get following error:

No database provider has been configured for this DbContext.

The connection string is read correctly from the appsettings file, am I missing something? I have read other posts where people just configure the connection part in the DB context but I would prefer to do it this way with injection.

Your constructor accepting a DbContextOptions is wrong. You need one that accepts one for your specific DbContext . So instead of:

public DB(DbContextOptions<DbContext> options) : base(options) { }

Use:

public DB(DbContextOptions<DB> options) : base(options) { }

These are the two constructors on your database context type DB :

public DB(DbContextOptions<DbContext> options) : base(options) { }
public DB() { }

So when the dependency injection container is attempting to resolve the database context, it looks at those constructors and tries to determine which constructor to use the create the object.

First, it will look at the one expecting a DbContextOptions<DbContext> argument. Usually, the DbContextOptions are automatically registered as part of the AddDbContext<T>() call. However, the types that are registered are DbContextOptions (non-generic) and DbContextOptions<T> .

So in your case, for a database context DB , only the types DbContextOptions and DbContextOptions<DB> are registered.

So the dependency injection container is not able to resolve DbContextOptions<DbContext> and as such cannot use that constructor. So it will use the next constructor which happens to be the empty constructor. Since the empty constructor does not support any configuration, the database context will be unconfigured and you will receive that error when attempting to use it.

The solution is pretty simple: Adjust the DbContextOptions<> type in that constructor. You can either use DbContextOptions or DbContextOptions<DB> . The latter is generally preferred since it allows you to have multiple database contexts in the same application but if you just have one, then you can also just use the former. I would also recommend you to remove the empty constructor to make sure that it won't be used accidentally:

public DB(DbContextOptions<DB> options)
    : base(options)
{ }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM