Reputation: 1543
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)
1 factory)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(FuncNo 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
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
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
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
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
Reputation: 2857
I had this problem after I've inlined Program.CreateWebHostBuilder
into Program.Main
. Had to extract it back.
Upvotes: -2
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
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
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