繁体   English   中英

部署到 Azure 时获取 DBContext 的连接字符串

[英]Getting connection string for DBContext when deploying to Azure

编辑:这个问题已经过重大重组,现在我已经弄清楚了更多的问题,这应该可以澄清一些事情。

我正在关注本教程: https://learn.microsoft.com/en-us/azure/app-service/tutorial-do.netcore-sqldb-app

我已经部署了自己的多项目应用程序,它可以正常工作,但我无法使连接字符串正常工作。 出于某种原因,它只有在我将连接字符串硬编码到我的 DBContext class 的 OnConfiguring 方法中时才有效。否则,它会抛出错误。

像这样:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
        .UseSqlServer(
                "Nasty hard coded azure connection string",
                providerOptions => { providerOptions.EnableRetryOnFailure(); });
    } 

但是,显然,我想从配置文件或环境变量中获取连接字符串。

在部署之前,我有以下内容。 用于设置连接字符串的 IServiceColleciton 的扩展方法:

public static void ConfigureSqlContext(this IServiceCollection services,
    IConfiguration configuration) =>
    services.AddDbContext<PeakedDbContext>(opts =>
 opts.UseSqlServer(configuration.GetConnectionString("defaultConnection")));

然后在program.cs中调用这个方法。 一个很正常的设置。

我还像这样设置了一个 IDesignTimeDBContextFactory:

 public class RepositoryContextFactory : IDesignTimeDbContextFactory<PeakedDbContext>
    {
        public PeakedDbContext CreateDbContext(string[] args)
        {
            var configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json")
            .Build();
            var builder = new DbContextOptionsBuilder<PeakedDbContext>()
            .UseSqlServer(configuration.GetConnectionString("defaultConnection"));
            return new PeakedDbContext(builder.Options);
        }
    }

我的 appsettings.json 和 Azure 应用服务配置都具有相同的名称“defaultConnection”。

据我所知,这是这里推荐的方法: https://learn.microsoft.com/en-us/ef/core/cli/dbcontext-creation?tabs=do.net-core-cli

我还尝试为我的 DBContext 添加一个空的构造函数。 (不确定这会如何影响事情,因为我的 DBContext 构造函数上有其他 DI。我的 DBContext 构造函数有点失控:

    public PeakedDbContext()
    {
    }

    public PeakedDbContext(DbContextOptions options) : base(options)
    {
    }

    public PeakedDbContext(DbContextOptions options, ICurrentUserService currentUserService) : base(options)
    {
        _currentUserService = currentUserService;
    }

根据上面的第二个链接,我的 DBContext 中不需要 OnConfiguring 方法......即使我需要,传递对 configuration.GetConnectionString 的访问权限的正确方法是什么,而不是对连接字符串进行硬编码? 我应该只添加另一个注入配置的 DBContext 构造函数吗? 但是,它只有在我有 onconfiguring 方法时才有效。 azure 应用服务未使用上下文工厂和扩展方法设置。

它不应该使用我在上面设置的设计时工厂或主机配置扩展方法吗? 使用 _configuration.GetConnectionString("defaultConnection") 以使其在本地和 Azure 部署上工作的正确方法是什么?

更新:仍然没有运气。 我尝试将数据库连接字符串添加为 azure 上的环境变量,如下所示: 在此处输入图像描述

然后更新我对 getconnection 字符串的所有引用 - 在 program.cs、IDesignFactory 和 OnConfiguring 中 - 如下所示:

Environment.GetEnvironmentVariable("PeakedDbConn")

这继续在本地工作。 但是当部署到 Azure 时,它声称 null 中的连接字符串......所以它没有看到这个变量。 我也找不到任何可以从图像访问 defaultConnection 的代码。 这很奇怪,因为它可以很好地访问 SECRET 变量。

我遵循了您提供的相同代码,并进行了一些更改。

检查以下步骤以从appsettings.json获取连接字符串,如果已设置Azure App Connection String ,则覆盖该值。

当您使用.NET Core 6时,我已经在Program.cs本身中设置了所有配置。

我的Program.cs

builder.Services.AddDbContext<MyDatabaseContext>(options =>
                    options.UseSqlServer(builder.Configuration.GetConnectionString("MyDbConnection")));
builder.Configuration.AddEnvironmentVariables();

LocalAzure App Connection Strings中必须存在相同的Connection String名称。

我的appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MyDbConnection": "Dummy Connection String"
  }
}

Azure 应用程序连接字符串:在此处输入图像描述

  • 为了检查我们是否正在获取Connection String值,我在 Controller 中编写了代码。
 private readonly IConfiguration Configuration;
 public HomeController(ILogger<HomeController> logger,IConfiguration config)
        {
            _logger = logger;
            Configuration = config;
        }
       
         public IActionResult Index()
        {
            var myconnStr = Configuration.GetConnectionString("MyDbConnection");           
            ViewBag.myconnStr = myconnStr;           
            return View();
        }

我的.csproj文件:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.2" />
    <PackageReference Include="Microsoft.Extensions.Configuration.AzureAppConfiguration" Version="5.2.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
  </ItemGroup>

</Project>

本地 Output:

在此处输入图像描述

已部署的应用程序 Output:在此处输入图像描述

好的,原来是 GitHub 操作才是问题所在。 我在第一个链接中遵循的教程没有提到这一点,也许是因为它是一个单一的项目 api... 不太确定。

本教程使用 github 操作来构建和部署应用程序,但对我来说,在构建过程中它失败了,说没有连接字符串。 这是因为 GitHub 构建过程无权访问您的本地变量或 azure 环境变量。

因此,我必须将 go 设置为我的 github 存储库,然后在左侧单击秘密和变量 < 操作。

单击创建一个新的 Repository Secret,将其命名为与您的环境变量相同的名称,即对我来说是 PEAKEDDBCONN。 然后,给它一个值。 我只是使用了我的本地主机字符串,但我想如果你愿意,你可以在这里输入“monkeynuts”,它只需要不是 null 即可。

然后,您需要在工作流 yaml 文件中添加一行,与教程中讨论的相同,以告知环境变量。 我是这样添加的:

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      PEAKEDDBCONN: ${{ secrets.PEAKEDDBCONN }}

然后一切都很好地构建并运行。

对于任何有帮助的人,我决定将整个设置写成博客: https://garyfrewin.hashnode.dev/setting-up-an-entity-framework-core-web-api-on-azure-with-sqlserver-a-爱好项目的分步指南

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM