【问题标题】:DbContext cannot find databaseDbContext 找不到数据库
【发布时间】:2016-01-04 10:33:24
【问题描述】:

我们应用的连接字符串设置在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

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

【问题讨论】:

  • 你不应该更新一个 dbcontext,它应该被注入到你需要的地方,因为它已经注册了服务
  • 如果你新建了CustomersContext,你应该使用接受IServiceProvider 和DbContextOptions 的构造函数。连接字符串来自 DbContextOptions,因此您的连接字符串没有得到一个,因为您更新它的方式。
  • 谢谢@Joe Audette。你能举出你提到的两种方法的例子吗?
  • code from one of my projects 中,您可以看到我的 LogRepository 获得了一个 IServiceProvider 和 DbContextOptions 注入到它的构造函数。然后这两个对象用于正确地新建我的 dbcontext。或者,您可以只依赖于 dbcontext 本身的构造函数,而不必自己新建它。我有一个example of that in another project here
  • 再次感谢@Joe Audette。如果您将您的 cmets 添加为答案,我可以将它们标记为答案。

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


【解决方案1】:

问题在于,尽管您已经使用 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))
 {
...
}

【讨论】:

  • 感谢您耐心地帮助我解决这个问题@Joe Audette
猜你喜欢
  • 1970-01-01
  • 2019-10-14
  • 1970-01-01
  • 1970-01-01
  • 2016-07-30
  • 1970-01-01
  • 2017-10-09
  • 1970-01-01
相关资源
最近更新 更多