我有一个Azure函数应用程序,该函数具有在Blob触发器上运行的功能。我已经证明此功能可以在Azure门户中运行,并且可以响应blob触发器而不会出现问题...或者至少可以做到。
现在,我已经添加了使用EF Core(2.2.4)的功能,无论是在本地调试还是在发布到Azure时,它都会给我以下错误:
Microsoft.Azure.WebJobs.Host:错误索引方法“ ParseThings”。 Microsoft.Azure.WebJobs.Host:无法将参数“上下文”绑定到AvastusContext类型。确保绑定支持参数类型。如果您使用绑定扩展(例如Azure存储,ServiceBus,Timer等),请确保已在启动代码中调用了扩展的注册方法(例如builder.AddAzureStorage(),builder.AddServiceBus( ),builder.AddTimers()等)。
我按照Azure Function App文档here的指示,拥有一个Startup
类,除了下面几行代替其配置的示例服务外,还沿用了他们的示例:
[assembly: FunctionsStartup(typeof(AvstFunctionApp.Startup))]
namespace AvstFunctionApp
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddDbContext<AvastusContext>(options => options.UseSqlServer(Environment.GetEnvironmentVariable("AvastusDb")));
}
}
}
函数的开头:
public static class ParseThings
{
[FunctionName("ParseThings")]
public static void Run([BlobTrigger("summaries/{name}", Connection = "StorageConnectionString")]Stream myBlob, string name, ILogger log, AvastusContext context)
我可以确认AddDbContext
行正在被调试器击中,因此大概是这里的幕后发生了一些错误,或者我做的事情太愚蠢了。
我尝试过的没用的东西包括:
.BuildServiceProvider(true)
行中添加AddDbContext
WebJobsStartup
代替最近发布的FunctionsStartup
Run
方法从静态更改为实例AvastusContext
的不正确名称空间还值得注意的是,此Function App项目中还有两个其他功能似乎没有任何严重的问题,并且我已经能够使用类似的方法将依赖项注入与EF Core一起用于另一个(此解决方案中的ASP.NET Core MVC)项目。
在此先感谢您提供任何帮助!
P.S。我发现非常怪异的是,internet上的.NET Core,Azure Function应用程序和EF Core的更高版本没有任何描述这种情况的东西,这使我相信这可能是一个简单的错误。希望不会。
答案 0 :(得分:0)
也许一种解决方案是,您可以尝试在函数中注入IServiceProvider而不是像在下面的存储库类中注入AvastusContext一样:
private readonly IServiceProvider serviceProvider;
public SomeRepository(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
using var context = this.serviceProvider.GetService<XYZDBContext>();
这将为您提供一个上下文对象。另外,不确定为什么要尝试直接在函数中访问上下文以作好实践,请定义一个上下文类,并维护存储库以执行代码中的任何CRUD操作。
Startup.cs,您可以添加其他配置,例如:
builder.Services.AddDbContext<XYZDBContext>(
options =>
{
options.UseSqlServer(
conn,
sqlServerOptionsAction:
sqlOptions =>
{
sqlOptions.EnableRetryOnFailure(maxRetryCount: 3, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
});
}, ServiceLifetime.Transient);
此配置在我当前的解决方案中工作得很好。试试看。
答案 1 :(得分:0)
函数应用无法解析函数中的 dbcontext,因为它只能解析 BindingContext。您需要创建自定义绑定才能在函数应用中直接使用 dbcontext。
通过 DI 注入 dbcontext 的其他方法是将其传递给构造函数并在函数中使用类级别变量。
public class ParseThings
{
private AvastusContext _context;
public ParseThings(AvastusContext context){
_context = context;
}
[FunctionName("ParseThings")]
public void Run([BlobTrigger("summaries/{name}", Connection = "StorageConnectionString")]Stream myBlob, string name, ILogger log){
// use _context here
}
}
如果仍然无法解决,您可能需要查看functionsStartup是否配置正确