在我的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'定义无参数的构造函数。
答案 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)