InvalidOperationException: No database provider has been configured for this DbContext

asp.net-core c# entity-framework-core

Question

context = new ApplicationDbContext();
context.Clients.Add(item);

InvalidOperationException: 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.

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {

        }

        public ApplicationDbContext()
        {

        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

        }

        public DbSet<Client> Clients { get; set; }

Startup

public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

            if (env.IsDevelopment())
            {
                // For more details on using the user secret store see https://go.microsoft.com/fwlink/?LinkID=532709
                builder.AddUserSecrets<Startup>();
            }

            builder.AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            services.AddMvc();

            // Add application services.
            services.AddTransient<IEmailSender, AuthMessageSender>();
            services.AddTransient<ISmsSender, AuthMessageSender>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
                app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseIdentity();

            // Add external authentication middleware below. To configure them please see https://go.microsoft.com/fwlink/?LinkID=532715

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

Updated

I added

// Startup.ConfigureServices
public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        //////my=>
        services.AddDbContext<DbContext>(config =>
        {
            config.UseSqlServer(Configuration.GetConnectionString("Default"));
        });

and configure it in your appsettings.json

    {
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-WebApplicationCore-42a4ac05-477c-4ea7-b286-87423170b48a;Trusted_Connection=True;MultipleActiveResultSets=true",
    "Default": "Server=(localdb)\\mssqllocaldb;Database=aspnet-WebApplicationCore-42a4ac05-477c-4ea7-b286-87423170b48a;"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  }
}

I clicked on the appsettings.json file and change the properties in the property window to "Build Action: Content" and "CopyToOutputDirectory: Copy Always"

<ItemGroup>
  <Content Update="appsettings.json">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </Content>
</ItemGroup>

Error not fixed

New error:

var result = await _userManager.CreateAsync(user, model.Password);

An unhandled exception occurred while processing the request. SqlException: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 50 - Local Database Runtime error occurred. Во время запуска экземпляра LocalDB произошла ошибка: ошибка запуска процесса SQL Server. )

System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, object providerInfo, bool redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, bool applyTransientFaultHandling)

1
0
4/28/2017 5:03:53 AM

Accepted Answer

You can't instantiate a DbContext without a parameterized constructor or an override to OnConfiguring.

You have two choices:

  1. Pass the DbContextOptions<ApplicationDbContext> via DI to your ApplicationDbContext. This is easiest done by configuring the ApplicationDbContext in your startup.cs and resolving it (without using new keyword!!!)

    // Startup.ConfigureServices
    services.AddDbContext<DbContext>(config => 
    {
        config.UseSqlServer(Configuration.GetConnectionString("Default"));
    });
    

    and configure it in your appsettings.json

    {
        "ConnectionStrings": {
            "Default": "YourSQLConnectionStringHere"
        }
    }
    
  2. Less recommended, because it requires hardcoding of the connection string, approach is to configure it within the DbContext

    public class ApplicationDbContext
    {
        public ApplicationDbContext(DbContextOptions options) : base(options) 
        {
        }
    
        // The call of the base constructor via ": base()" is still required
        public ApplicationDbContext(DbContextOptions options) : base() 
        {
        }
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(Configuration.GetConnectionString("connectionStringHere"));
            base.OnConfiguring(optionsBuilder);
        }
    }
    

Update

In response to the comments, you need to add

<ItemGroup>
  <Content Update="appsettings.json">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </Content>
</ItemGroup>

in order for the appsettings.json to be copied over to the output directory. Or just click on the appsettings.json file and change the properties in the property window to "Build Action: Content" and "CopyToOutputDirectory: Copy Always"

4
4/27/2017 7:00:29 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow