4

我有一个 Azure 函数应用程序,其函数在 blob 触发器上运行。我已经证明这个函数可以通过 Azure 门户运行,并且可以毫无问题地响应这个 blob 触发器......或者至少它确实如此。

现在我添加了使用 EF Core (2.2.4) 的功能,在本地调试和发布到 Azure 时都会出现以下错误:

Microsoft.Azure.WebJobs.Host:索引方法“ParseThings”出错。Microsoft.Azure.WebJobs.Host:无法将参数“上下文”绑定到 AvastusContext 类型。确保绑定支持参数类型。如果您正在使用绑定扩展(例如 Azure 存储、ServiceBus、计时器等),请确保您已在启动代码中调用了扩展的注册方法(例如 builder.AddAzureStorage()、builder.AddServiceBus( )、builder.AddTimers() 等)。

我有一个按照 Azure Function App 文档hereStartup指示的课程,并按照他们的示例进行操作,除了以下行代替他们配置的示例服务:

[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
  • 降级到 .NET Core 2.2.0
  • 将 Function 类和Run方法从静态更改为实例
  • 修复注入的不正确的命名空间AvastusContext

还值得注意的是,这个 Function App 项目中还有另外两个函数似乎没有任何严重的问题,而且我已经能够使用与 EF Core 类似的方法来实现依赖注入工作(ASP.NET此解决方案中的核心 MVC)项目。

提前感谢您提供的任何帮助!

PS 我觉得非常奇怪的是,在互联网上没有任何描述这种情况的 .NET Core、Azure Function Apps 和 EF Core 的更高版本,这让我相信这可能是一个简单的错误。希望不会。

4

2 回答 2

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 是否配置正确

于 2021-08-02T07:02:51.973 回答
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);

此配置在我当前的解决方案中运行良好。试试这个。

于 2020-07-30T08:14:53.620 回答