HungryHippos
HungryHippos

Reputation: 1543

No database provider has been configured for this DbContext .NET Core with SQL Server

I have been banging my head against a wall with this one and have been googling to no avail.

I have just started a new ASP.NET Core MVC project, I have installed/updated my packages for these two to 2.2.0:

Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools

I have set the project to expect .NET Core 2.2.0 as well.

I am able to successfully add my table schemas with this command in Package Manager console to scaffold the Database, so I know the connection string is fine/working:

Scaffold-DbContext "SERVER=Server\Instance;DATABASE=Database;UID=user;PWD=password;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Tables Table1, Table2, Table3

The created model file, DatabaseDBContext.cs looks like this:

public partial class DatabaseDBContext : DbContext
{
    public DatabaseDBContext()
    {
    }

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

This also contains a method that works to retrieve my scaffold data, but isn't considered safe for production use so I commented this out:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (!optionsBuilder.IsConfigured)
    {
        optionsBuilder.UseSqlServer("SERVER=Server\\Instance;DATABASE=Database;UID=user;PWD=password;");
    }
}

I added this same connection string to the appsettings.json file:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ConnectionStrings": {
    "DBConnString": "SERVER=Server\\Instance;DATABASE=Database;UID=user;PWD=password;"
  }
}

I then added the DbContext to the startup.cs file:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    services.AddDbContext<DatabaseDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DBConnString")));
}

Trying to add a new scaffolded controller for one of the tables throws this error:

Finding the generator 'controller'...
Running the generator 'controller'...
Attempting to compile the application in memory.
Attempting to figure out the EntityFramework metadata for the model and DbContext: 'TableName'

No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for DbContext.

StackTrace:
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize(IServiceProvider scopedProvider, IDbContextOptions contextOptions, DbContext context)
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.Internal.InternalAccessorExtensions.GetService[TService](IInfrastructure1 accessor)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func
1 factory)

No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for DbContext.

Has anyone got any clue what I am doing wrong here?

Upvotes: 9

Views: 39674

Answers (8)

Jos&#233; Y&#225;nez
Jos&#233; Y&#225;nez

Reputation: 170

Use only one constructor in the application DbContext:

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

Then make sure you use DI when accessing the context:


private DatabaseDBContext _context;

public AccountService(DatabaseDBContext context)
{
_context = context;
}

public async Task DoSomething()
{
 /*...*/
 _context.Add(something);
 await _context.SaveChangesAsync();
}

Upvotes: 0

Shaahin
Shaahin

Reputation: 1225

In my case, I used services to communicate with database and UnitOfWork, but in service constructor I have not dependency injection and just made new instance of DbContext class. It worked fine if I had hardocde DbContextOptionsBuilder in context which generates automatically, but in case of moving it to program.cs I got this error. Problem solved by using dependency injection in service constructor.

Upvotes: 0

Ankita_Shrivastava
Ankita_Shrivastava

Reputation: 1235

It was wired but fixed this issue by updating the framework version of the project solution. For example, I created one core repo on 3.0 and later installed the latest version 3.1 on the system so it was expecting to be updated with the latest version. I changed it and it worked!

Upvotes: 0

Fernando Moreira
Fernando Moreira

Reputation: 784

After battleing with this issue I've encounter the solution for it here

https://github.com/aspnet/EntityFrameworkCore/issues/12331

The problem was that Add-Migration was expecting the CreateWebHostBuilder

public static IWebHostBuilder CreateWebHostBuilder(string[] args)

Before my public static void Main(string[]) was running the WebHost without the static CreateWebHostBuilder and that after I added the Static function then it worked.

Upvotes: 1

Mikhail Orlov
Mikhail Orlov

Reputation: 2857

I had this problem after I've inlined Program.CreateWebHostBuilder into Program.Main. Had to extract it back.

Upvotes: -2

HungryHippos
HungryHippos

Reputation: 1543

So I fixed but it in a really roundabout way. My new project was originally on an older version of .net core. I had updated the version but there must have been something it didn't like during the update. I created a new project and started it on 2.2.0, then it worked...

The code logic was sound above. Still needed the same packages:

Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools

Startup.cs seems quite different, so maybe if anyone else sees this they could try updating the startup.cs code:

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddDbContext<DatabaseDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DatabaseDBConnString")));

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Had to add a reference to startup.cs for this:

using Microsoft.EntityFrameworkCore;

That was needed for the AddDbContext method to resolve.

After doing this the scaffolding now works. So it's fixed, but it required me to start over to fix it.

Upvotes: 5

SteinTech
SteinTech

Reputation: 4068

I had the same problem and this solved it for me (setting UseSqlServer in OnConfiguring):

protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
    if (!builder.IsConfigured)
    {
        string conn = this.IsProduction ? Const.ProductionConnectionString : Const.LocalDBConnectionString;

        builder.UseSqlServer(conn);
    }

    base.OnConfiguring(builder);
}

Upvotes: 4

Michael Ceber
Michael Ceber

Reputation: 2452

Try add this 3rd constructor:

public DatabaseDBContext()
{
}

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

public DatabaseDBContext(DbContextOptions options)
    : base(options)
{
}

Then chuck a breakpoint in each one just so you are sure which one is actually getting used.

Upvotes: -2

Related Questions