【发布时间】:2020-01-04 01:32:25
【问题描述】:
我有一个现有的 EF Core 2.2 DbContext 可以在 ASPNET Core 应用程序和 LinqPad 中正常工作。现在我正在尝试将它添加到 Azure 函数中。在 ASPNET 和 Azure 函数中,我都在使用依赖注入。
DbContext 类具有三个构造函数 - 一个为空,一个接受连接字符串,另一个接受 DbOptionsBuilder 实例。 ASPNET Core 应用程序似乎调用了采用 DbOptionsBuilder 实例的应用程序,而 LinqPad 使用了采用连接字符串的应用程序。正如我所说,这两个都可以正常工作。
Azure 函数应用尝试使用接受字符串的函数应用,但它传递的是 null 而不是值。这会导致稍后出现错误,提示尚未配置提供程序。
我可以强制函数应用使用DbOptionsBuilder 构造函数,方法是删除接受字符串的构造函数。当我这样做时,功能应用程序工作正常。但是,如果我这样做了,我将无法再在 LinqPad 中使用上下文。
我的问题是,首先,如何让 Azure 函数调用适当的构造函数而不删除其他构造函数?其次,也是不太重要的,为什么 ASPNET 运行时和 Azure 函数运行时之间的行为不同?
编辑 我此时仅在本地运行 AZ 函数,因此它正在从“local.settings.json”文件中读取连接字符串。这部分工作正常。
这里是函数项目的Startup.Configure方法。
public class Startup : FunctionsStartup
{
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the DI container.
/// </summary>
/// <param name="builder">The function host builder</param>
public override void Configure(IFunctionsHostBuilder builder)
{
// Add database context
string env = Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT");
string connectionString = Environment.GetEnvironmentVariable($"ConnectionStrings:{env}");
builder.Services.AddDbContext<FullContext>(x => x.UseSqlServer(connectionString), ServiceLifetime.Transient);
}
}
正如我所说,它正在读取连接字符串并似乎将其传递给 AddDbContext 方法。但是某处出了点问题。
编辑 2
这是我的DbContext 子类中的三个构造函数。没什么特别的。还包括OnConfiguring 方法。
public FullContext() { }
public FullContext(string connectionString)
{
ConnectionString = connectionString;
}
public FullContext(DbContextOptions<FullContext> options) : base(options) { }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (ConnectionString != null)
optionsBuilder.UseSqlServer(ConnectionString);
base.OnConfiguring(optionsBuilder);
}
编辑 3 在查看了@Jack Jia 建议的链接后,我尝试了以下操作。
首先,我创建自己的DbContextOptionsBuilder 实例并指定提供程序和连接字符串。
var options = new DbContextOptionsBuilder<FullContext>();
options.UseSqlServer(connectionString);
然后我尝试强制 DI 服务使用这些选项。但是,使用 AddDbContext 方法时会失败 - 它仍然尝试使用空字符串作为参数调用错误的构造函数。
换句话说,这失败了:
builder.Services.AddDbContext<FullContext>(x => new FullContext(options.Options), ServiceLifetime.Transient);
但这似乎有效:
builder.Services.AddTransient<FullContext>(x => new FullContext(options.Options));
假设我正确理解了文档,这两个调用都应该强制 DI 服务使用带有 DbContextOptions 参数的构造函数。但这似乎并非如此。
【问题讨论】:
-
取决于你如何注册上下文(你没有显示)
-
如果没有minimal reproducible example 明确指出已完成的工作,就很难重现问题,从而更好地理解所询问的内容。
标签: asp.net-core entity-framework-core azure-functions