【问题标题】:A named connection string was used, but the name 'DefaultConnection' was not found in the application's configuration使用了命名连接字符串,但在应用程序的配置中找不到名称 \'DefaultConnection\'
【发布时间】:2022-09-24 01:35:53
【问题描述】:

我的 DOTNET 6 API 中有一个名为 FileManagerContext 的 DbContext:

public class FileManagerContext : DbContext {
    public FileManagerContext(DbContextOptions<FileManagerContext> options) : base(options) { }
    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        base.OnModelCreating(modelBuilder);
        modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly);
    }
}

这是一个非常简单的DbContext,里面有一个简单的实体。无论如何,我也有这个appsettings.json:

{
  \"Logging\": {
    \"LogLevel\": {
      \"Default\": \"Information\",
      \"Microsoft.AspNetCore\": \"Warning\"
    }
  },
  \"ConnectionStrings\": {
    \"DefaultConnection\": \"Server=localhost;Database=FM;User=SA;Password=1234;\"
  },
  \"AllowedHosts\": \"*\"
}

这是Program.cs\'s 顶级语句中的启动sn-p:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<FileManagerContext>(
    opt => opt.UseSqlServer(\"name=DefaultConnection\"));

在这种情况下,我可以使用迁移。一切顺利。我可以添加迁移,并且可以成功更新数据库。但是当我运行应用程序并尝试使用 DbContext 时,我收到了这个错误:

System.InvalidOperationException:使用了命名连接字符串, 但在应用程序中找不到名称 \'DefaultConnection\' 配置。请注意,仅支持命名连接字符串 当使用 \'IConfiguration\' 和服务提供者时,例如在 典型的 ASP.NET Core 应用程序。看 https://go.microsoft.com/fwlink/?linkid=850912 了解更多信息。

我也尝试过像这样获取连接字符串:

var cs = builder.Configuration.GetConnectionString(\"DefaultConnection\");

但它返回null。有人可以帮我解决吗?

    标签: c# .net-core entity-framework-core .net-6.0 ef-core-6.0


    【解决方案1】:

    从错误的声音来看,您的配置可能没有被拾取。

    配置是如何创建的?

    您是否看到在 Webhost 上调用了 AddConfiguration 扩展方法?该方法的内容应类似于以下内容:

    IConfiguration config = new ConfigurationBuilder()
                              .SetBasePath(Directory.GetCurrentDirectory())
                              .AddJsonFile("appsettings.json", false, false)                                           
                              .AddJsonFile($"appsettings.{envLower}.json", true, true)
                              .AddEnvironmentVariables()
                              .Build();
    

    构建的调用可能存在也可能不存在。我们通常手动创建配置对象,因为我们需要构建 Loggers,然后使用 AddConfiguration 扩展方法将该对象添加到主机。

    如果您没有看到,请查看 Microsoft 的文档以获取有关如何设置的指导。 Configuration Documentation

    或者,您可以通过配置对象获取连接字符串并将其传递给 UseSqlServer 方法。

    services.AddDbContext<FileManagerContext>((provider, options) => {
               IConfiguration config = provider.GetRequiredService<IConfiguration>();
               string connectionString = config.GetConnectionString("DefaultConnection");
               options.UseSqlServer(connectionString);                             
             });
    

    在替代方法中,将服务提供者传递给操作。您可以使用提供程序从 DI 容器中获取 IConfiguration 对象。

    【讨论】:

    • 基本路径、json 文件(包括环境覆盖)、环境变量,甚至命令行参数都默认在 .NET core 6 中使用单行 WebApplication.CreateBuilder(args); 完成
    【解决方案2】:

    使用builder.Configuration

    builder.Services.AddDbContext<FileManagerContext>(options => 
    {
        options.UseSqlServer(builder.Configuration["ConnectionStrings:DefaultConnection"]);
    });
    

    或@Serge 提到的builder.Configuration.GetConnectionString

    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
    

    【讨论】:

      【解决方案3】:

      不要使用“name=DefaultConnection”,因为它被视为连接字符串名称,包括“name=”

      我在 program.cs 中使用此语法,一切正常

      var builder = WebApplication.CreateBuilder(args);
      
      .......
      
      builder.Services.AddDbContext<FileManagerContext>(options => 
      options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
      

      并且由于您使用的是 Ms Sql Server ,因此 sql server 的连接字符串通常是这样的

      "DefaultConnection": "Data Source=xxxx;Initial catalog=xxx;Integrated Security=False;User ID=xxxx;Password=xxxx;"
      

      我的 OnConfiguring 代码看起来像这样

      protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
      {
         if (!optionsBuilder.IsConfigured)
         {
             ...your code
          }
      }
      

      【讨论】:

      • 我已经试过没有name=;没有区别。也正如我在 Q builder.Configuration.GetConnectionString 中提到的返回 null。
      【解决方案4】:

      感谢@Neil 我想通了。配置未加载到应用程序中。但是,由于我在 dotnet 6 的顶级语句中,添加配置似乎与@Neil 的建议有点不同。所以这是可行的解决方案:

      builder.Services.AddControllers();
      
      var currentDirectory = AppDomain.CurrentDomain.BaseDirectory;
      var environmentName = builder.Environment.EnvironmentName;
      
      builder.Configuration
          .SetBasePath(currentDirectory)
          .AddJsonFile("appsettings.json", false, true)
          .AddJsonFile($"appsettings.{environmentName}.json", true, true)
          .AddEnvironmentVariables();
      
      // blah blah 
      builder.Services.AddDbContext<FileManagerContext>(
          opt => opt.UseSqlServer("name=DefaultConnection"));
      

      【讨论】:

      • 有同样的上述问题,使用上面的代码,但仍然无法正常工作
      【解决方案5】:

      我试图通过这个命令来搭建数据库更改:

      Scaffold-DbContext -Connection name=YourDBContextObjectName -Provider 
        Microsoft.EntityFrameworkCore.SqlServer -project Destination_NameSpace 
          -context YourDBContextObjectName -OutputDir Entities -force
      

      但是问题在代码优先方法中也是一样的,在我的场景中,我有不同的应用设置适用于不同的 ENV。

      这appSettings.json就像这样(如你所见,有连接字符串此文件中的信息:

      还有,我的appsettings.dev.json就像这样:

      出现问题是因为当我尝试通过命令构建数据库更改时,首先它尝试构建您的项目,并且因为雷迪斯和兔MQ连接信息丢失在应用设置.json文件,它无法连接到数据源。所以它返回错误。

      访问 Microsoft.Extensions.Hosting 服务时出错。在没有应用程序服务提供商的情况下继续。错误:对象引用未设置为对象的实例。 System.InvalidOperationException:使用了命名连接字符串,但在应用程序的配置中找不到名称“DBContextName”。请注意,仅在使用“IConfiguration”和服务提供者时才支持命名连接字符串...

      解决方案 :

      1. 将正确的项目设置为启动项目
      2. 将有关其他连接的缺失信息添加到应用设置.json

        如您所见,无论错误如何,它并不总是与数据库连接字符串相关。

      【讨论】:

        【解决方案6】:

        我有同样的问题,但是当应用程序在服务器上发布时发生错误。我的字符串连接在用户的秘密中,我所做的如下:

        在 program.cs 中

        // Add services to the container.

        builder.Services.AddDbContext<DataContext>(options =>
        {
            options.UseSqlServer("Name=dbconnection");
        });
        builder.Services.AddDbContext<DataContext>();
        

        并且在发布之前,在数据库选项中选择字符串连接并确保它是正确的:

        Publish Options

        它适用于 dot 6 API

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-04-02
          • 1970-01-01
          • 1970-01-01
          • 2015-07-17
          • 2012-06-14
          • 1970-01-01
          • 1970-01-01
          • 2012-06-14
          相关资源
          最近更新 更多