问题
The connection string for our app is set in appsettings.json
"Data": {
"DefaultConnection": {
"ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Customers;Trusted_Connection=True;MultipleActiveResultSets=true",
In ConfigureServices
we have
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<CustomersContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
This seems to work in cases like this
var membershipUser = await _userManager.FindByEmailAsync(email);
and this
var result = await _userManager.CreateAsync(newUser);
but falls over when I try this
using (var customers = new CustomersContext())
{
var deviceList = customers.Devices.Where(d => d.UserId == membershipUser.Id);
The error is InvalidOperationException: No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services.
If I try this
public partial class CustomersContext : IdentityDbContext<ApplicationUser>
// note this inherits from IdentityDbContext<ApplicationUser> not DbContext
// refer http://stackoverflow.com/questions/19902756/asp-net-identity-dbcontext-confusion
{
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer(@"Server=(localdb)\\mssqllocaldb;Database=Customers;Trusted_Connection=True;MultipleActiveResultSets=true");
}
I get this error
Local Database Runtime error occurred. Specified LocalDB instance name is invalid
Why is it my app can find the database in some cases but not others?
回答1:
The problem is that although you've configured a CustomerContext with the DI services as shown here:
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<CustomersContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
You are not having the CustomerContext injected, instead you are newing it up like this:
using (var customers = new CustomersContext())
{
...
}
using a constructor that takes no parameters, so your CustomersContext is not configured like the one in startup and it has no connection string.
Since you mention you need it in the AccountController, then all you need to do is add CustomersContext to the constructor of AccountController, so that the one you configured in startup will get injected. Like this:
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
private readonly ISmsSender _smsSender;
private readonly ILogger _logger;
private CustomersContext _customerContext;
public AccountController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ISmsSender smsSender,
ILoggerFactory loggerFactory,
CustomersContext customerContext)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_smsSender = smsSender;
_logger = loggerFactory.CreateLogger<AccountController>();
_customerContext = customerContext;
}
That way you get a properly configured CusotmersContext and you don't have to new it up yourself. If for some reason you did want to new it up yourself you need to do so using a constructor that takes IServiceProvider and DbContextOptions. So you would receive those objects in the constructor of AccountController and you would pass them in as you new up the CustomersContext like this:
using (var customers = new CustomersContext(serviceProvider, dbContextOptions))
{
...
}
来源:https://stackoverflow.com/questions/34589158/dbcontext-cannot-find-database