DbContext找不到数据库

时间:2016-01-04 10:33:25

标签: asp.net-core asp.net-core-mvc entity-framework-core asp.net-identity-3

我们的应用的连接字符串在appsettings.json

中设置
  "Data": {
"DefaultConnection": {
  "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Customers;Trusted_Connection=True;MultipleActiveResultSets=true",

ConfigureServices我们有

            services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<CustomersContext>(options =>
                options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

这似乎适用于这样的情况

var membershipUser = await _userManager.FindByEmailAsync(email);

和这个

var result = await _userManager.CreateAsync(newUser);

但是当我尝试这个时会失败

            using (var customers = new CustomersContext())
        {
            var deviceList = customers.Devices.Where(d => d.UserId == membershipUser.Id);

错误为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.

如果我试试这个

            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");
    }

我收到此错误

Local Database Runtime error occurred. Specified LocalDB instance name is invalid

为什么我的应用程序可以在某些情况下找到数据库而不是其他情况?

1 个答案:

答案 0 :(得分:4)

问题在于,尽管您已使用DI服务配置了CustomerContext,如下所示:

services.AddEntityFramework()
        .AddSqlServer()
        .AddDbContext<CustomersContext>(options =>
           options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

您没有注入CustomerContext,而是按照以下方式新建它:

using (var customers = new CustomersContext())
 {
...
}

使用不带参数的构造函数,因此您的CustomersContext配置不像启动时那样,并且没有连接字符串。

由于您在AccountController中提到需要它,因此您需要做的就是将CustomersContext添加到AccountController的构造函数中,以便在启动时配置的那个将被注入。像这样:

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;
}

通过这种方式,您可以获得正确配置的CusotmersContext,而且您不必自己修改它。如果由于某种原因你确实想要自己创建它,你需要使用一个带有IServiceProvider和DbContextOptions的构造函数。所以你会在AccountController的构造函数中收到这些对象,你可以在新建CustomersContext时传递它们,如下所示:

using (var customers = new CustomersContext(serviceProvider, dbContextOptions))
 {
...
}