Azure Functions环境变量始终为null

时间:2020-06-13 06:31:18

标签: c# azure entity-framework-core azure-functions

在我的V3函数项目中,我试图连接实体框架并传递来自环境变量的连接字符串。

在我的local.settings.json文件中:

{
  "Values" : {
    "SqlConnectionString" : "<localdb connection string here>"
  }
}

我正在按照this blog post使用IDesignTimeContextFactory连接上下文:

public class ContextFactory : IDesignTimeDbContextFactory<Context>
    {
        public Context CreateDbContext(string[] args)
        {
            var optionsBuilder = new DbContextOptionsBuilder<Context>();
            var connectionString = Environment.GetEnvironmentVariable("SqlConnectionString", EnvironmentVariableTarget.Process);
            optionsBuilder.UseSqlServer(connectionString);

            return new Context(optionsBuilder.Options);
        }
    }

当我尝试添加迁移时,connectionString为空。

有人可以看到这里的问题吗?

编辑:

根据建议,我还尝试过定义连接字符串并像这样注入IConfiguration:

    public class ContextFactory : IDesignTimeDbContextFactory<Context>
    {
        private readonly IConfiguration _configuration;

        public ContextFactory(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        public Context CreateDbContext(string[] args)
        {
            var optionsBuilder = new DbContextOptionsBuilder<Context>();
            optionsBuilder.UseSqlServer(_configuration.GetConnectionString("SqlConnectionString"));

            return new Context(optionsBuilder.Options);
        }
    }

但出现以下异常:

System.MissingMethodException:没有为类型'EbayTools.Functions.Domain.ContextFactory'定义无参数的构造函数。

4 个答案:

答案 0 :(得分:4)

EXPLANATION

我在遵循相同的博客文章/教程时遇到了相同的问题!

运行Entity Framework Core CLI工具时,local.settings.json中的值不会添加到环境变量列表中。您可以通过提示调试器运行来进行检查(请参见代码)。

要在运行Entity Framework Core CLI命令时访问local.settings.json中的值,我使用了ConfigurationBuilder(再次参见下文)。

最后,我将连接字符串存储在local.settings.json文件中的“值”下,而不是ConnectionStrings中。


解决方案

ProjectContextFactory.cs

public class ProjectContextFactory : IDesignTimeDbContextFactory<ProjectDbContext>
{
    public ProjectDbContext CreateDbContext(string[] args)
    {
        // Prompt debugger to open when running ef cli command.
        // Remove this when you no longer need to debug
        Debugger.Launch();

        // See that environment variables list doesn't contain your key value and therefore connectionString variable returns null
        var variables = Environment.GetEnvironmentVariables();
        var connectionString = Environment.GetEnvironmentVariable("SQLDB_CONNECTIONSTRING");

        // Setup config
        var config = new ConfigurationBuilder()
            .SetBasePath(Path.Combine(Directory.GetCurrentDirectory()))
            .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables()
            .Build();

        // Get connection string from config
        var connectionString = config.GetValue<string>("Values:SQLDB_CONNECTIONSTRING");

        var optionsBuilder = new DbContextOptionsBuilder<ProjectDbContext>();
        optionsBuilder.UseSqlServer(connectionString);

        return new ProjectDbContext(optionsBuilder.Options);
    }
}

local.settings.json

{
   "IsEncrypted": false,
   "Values": { 
       "AzureWebJobsStorage": "UseDevelopmentStorage=true",
       "SQLDB_CONNECTIONSTRING": "<connectionString>
   }
}

答案 1 :(得分:1)

您可以在IConfiguration中注入Startup(),如下所示:

var configuration = builder.Services.BuildServiceProvider().GetService<IConfiguration>(); 
var connString = configuration.GetConnectionString("DataContext");

带有local.settings.json文件:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
  },
  "ConnectionStrings": {
    "StorageConnectionString": "aaaa",
  }
}

IConfiguration将在Azure中托管时自动从功能应用程序设置中读取,而local.settings.json在本地运行时将自动读取。

对于您的错误消息,您可以参考此article

答案 2 :(得分:0)

您做错了Environment.GetEnvironmentVariable检索环境变量的值。

我建议您在appsettings.json文件中定义连接字符串,并像这样使用它。

appsettings.json

  "ConnectionStrings": {
    "DB": "Data Source=Server;Initial Catalog=DBName;User ID=UserId;Password=password-"
  }

C#代码

private IConfiguration _configuration { get; set; }
_configuration.GetConnectionString("DB");

您需要将IConfiguration注入所需的类。

答案 3 :(得分:0)

如果 Visual Studio 2019 对我不起作用。

此解决方案仅适用于使用 Visual Studio 代码创建的 azure 函数

像这样访问环境变量-

var APIToInvoke = System.Environment.GetEnvironmentVariable("APIToInvoke", EnvironmentVariableTarget.Process);

但是imp,应该使用visual studio 代码创建和部署azure 函数。部署后,您将看到按钮上传设置,使用它从 local.settings.json 文件上传设置。然后它会起作用。

enter image description here