使用Mediatr - DbContext错误触发Azure功能队列

问题描述 投票:0回答:1

我正在实现Queue触发的azure函数 - 我正在使用名为Mediatr的Mediator Pattern库来增强命令查询隔离 - 并根据以下教程使用Azure Function中的最新运行时(2.0.12382.0)构造函数依赖注入https://devkimchi.com/2019/02/22/performing-constructor-injections-on-azure-functions-v2/

对于每个Azure函数触发器,我调用Mediatr CommandHandler但我收到错误:

“在上一个操作完成之前,第二个操作在此上下文中启动。这通常是由使用相同DbContext实例的不同线程引起的,但实例成员不保证是线程安全的。这也可能是由于要评估的嵌套查询引起的在客户端上,如果是这种情况,则重写查询以避免嵌套调用。“

该错误表明我正在尝试从并行任务访问同一个DbContext实例。但是我只有一个命令处理程序(Mediatr Handler)和一个查询处理程序。我正在使用构造函数注入

我试图在启动时将Meditr服务更改为瞬态,但在测试azure函数模拟器中的函数时仍会收到相同的错误

启动类

public class StartUp : IWebJobsStartup
{

    public void Configure(IWebJobsBuilder builder)
    {
        var configuration = new ConfigurationBuilder()
             .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
             .AddEnvironmentVariables()
             .Build();
        var connection = configuration.GetConnectionString("Default"); 
        builder.Services.AddDbContext<CoreDBContext>(options =>
        {
            options.UseSqlServer(connection, p =>
            {
                p.MigrationsAssembly("B12Core.Persistence");
            });
        }
        );
        builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>));
        builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPerformanceBehaviour<,>));
        builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestValidationBehavior<,>));
        builder.Services.AddMediatR(p =>
        {
            p.AsTransient();

        }, typeof(CreateMessageCommand).GetTypeInfo().Assembly);
    }
}

完全错误

System.Private.CoreLib:执行函数时出现异常:Function1。 Microsoft.EntityFrameworkCore:在上一个操作完成之前,在此上下文中启动了第二个操作。这通常是由使用相同DbContext实例的不同线程引起的,但实例成员不保证是线程安全的。这也可能是由在客户端上评估的嵌套查询引起的,如果是这种情况则重写查询以避免嵌套调用。

entity-framework-core azure-functions dbcontext azure-functions-runtime mediatr
1个回答
0
投票

通过将db上下文注入生命周期更改为ServiceLifetime.Transient来解决此问题

 builder.Services.AddDbContext<CoreDBContext>(options =>
            {
                options.UseSqlServer(connection, p =>
                {
                   p.MigrationsAssembly("Presistence");
                });
            },ServiceLifetime.Transient
            );
© www.soinside.com 2019 - 2024. All rights reserved.