Jakov Jakov -4 years ago 441
C# Question

No db context provider has been configure for this DbContext... although it has

Have a solution with 3 assemblies: Data, Domain and Web. Data holds the context, Web is a .NET Core WebAPI app, and they're all in the same solution directory. I'm also using Postgre as the database.

Here's my

ConfigureServices
method in
Startup.cs
:

public void ConfigureServices(IServiceCollection services)
{
string connectionString = Configuration.GetConnectionString("DefaultConnection");
...
services.AddDbContext<WebStoreContext>(
options => options.UseNpgsql(
connectionString,
(providerOptions) =>
{
providerOptions.CommandTimeout(20);
providerOptions.MigrationsAssembly("WebStore.Data");
}));

services.AddMvc();
...
}


Notice how a database provider has been configured by using
AddDbContext
and passing the
optionsAction
parameter.

Now I've created an initial migration for the db, using the command line ef tool.
I've cd-ed into WebStore.Data and ran:

dotnet ef --startup-project ..\WebStore.Web migrations add IntializeDb


That's all good.

The problem begins when I try to, from the same directory, run:

dotnet ef database update



No parameterless constructor was found on 'WebStoreContext'. Either add a parameterless constructor to 'WebStoreContext' or add an implementation of 'IDbContextFactory' in the same assembly as 'WebStoreContext'.


The above error I get before I declare a parameterless constructor in my DbContext derived class, and the below error after I declare one:


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.


So it seems to me like the paramterless constructor keeps getting called despite me providing a DbContextOptions instance.

So then I tried this:

//parameterless constructor calling the one accepting the DbContextOptions argument
public WebStoreContext() : this(new DbContextOptionsBuilder<WebStoreContext>()
.UseNpgsql("UserID=****;Password=****;Host=localhost;Port=****;Database=webstore;Pooling=true;")
.Options){ }


and got this:


System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileLoadException: Could not load file or assembly 'System.Diagnostics.DiagnosticSource, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)


Still trying to figure out what's going on here. Help would be greatly appreciated.

EDIT:
I applied Shay Rojansky's solution and it worked, although I had the following issue:


System.IO.FileLoadException: Could not load file or assembly
'System.Diagnostics.DiagnosticSource, Version=4.0.1.1,
Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The located
assembly's manifest definition does not match the assembly reference.
(Exception from HRESULT: 0x80131040) File name:
'System.Diagnostics.DiagnosticSource, Version=4.0.1.1,
Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' at
Microsoft.EntityFrameworkCore.Infrastructure.RelationalServiceCollectionExtensions.AddRelational(IServiceCollection
services) at
Microsoft.Extensions.DependencyInjection.NpgsqlEntityFrameworkServicesBuilderExtensions.AddEntityFrameworkNpgsql(IServiceCollection
services) at
Microsoft.EntityFrameworkCore.Internal.ServiceProviderCache.<>c__DisplayClass4_1.b__2(Int64
k) at
System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey
key, Func`2 valueFactory) at
Microsoft.EntityFrameworkCore.DbContext.InitializeServices() at
Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at
Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1
accessor) at
Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1
factory) at
Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String
contextType) at
Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String
targetMigration, String contextType) at
Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_1.<.ctor>b__0()
at
Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action
action)

Could not load file or assembly
'System.Diagnostics.DiagnosticSource, Version=4.0.1.1,
Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The located
assembly's manifest definition does not match the assembly reference.
(Exception from HRESULT: 0x80131040)


To which the solution is adding this to the .csproj file:

<PropertyGroup>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
</PropertyGroup>


This happens apparently due to a bug.

Answer Source

Try adding an OnConfiguring method to your context, as suggested by the EF Core getting started docs:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
    optionsBuilder.UseNpgsql("...");
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download