MassTransit 帮助注册多个传奇

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

我正在努力将旧应用程序移植到 .net6,并遇到了通过公共交通注册多个传奇的问题。

services.AddMassTransit<IProcessManagerBus>(busCfg =>
{
    busCfg.AddSagaStateMachine<OrderPM, OrderPMState>()
        .EntityFrameworkRepository<OrderPMState>(efConfig =>
        {
            efConfig.ConcurrencyMode = ConcurrencyMode.Optimistic;
            efConfig.DatabaseFactory(() => new OrderStateDbContext(configuration.GetConnectionString("DB")));
        });
    
    busCfg.AddSagaStateMachine<CsaLoginPM, CsaLoginPMState>()
        .EntityFrameworkRepository<CsaLoginPMState>(efConfig =>
        {
            efConfig.ConcurrencyMode = ConcurrencyMode.Optimistic;
            efConfig.DatabaseFactory(() => new CsaLoginStateDbContext(configuration.GetConnectionString("DB")));
        });
    
    busCfg.UsingRabbitMq((context, rabbitCfg) =>
    {
        rabbitCfg.UseJsonSerializer();
        rabbitCfg.Host(new Uri(configuration.GetValue<string>("messaging:pm-bus:host-address")), hostCfg =>
        {
            hostCfg.Username(configuration.GetValue<string>("messaging:pm-bus:username"));
            hostCfg.Password(configuration.GetValue<string>("messaging:pm-bus:password"));        
            
            rabbitCfg.ReceiveEndpoint(configuration.GetValue<string>("messaging:pm-bus:receive-queue"), epCfg =>
            {
                epCfg.PrefetchCount = 10;
                epCfg.UseRetry(retryConfig => retryConfig.Exponential(5, TimeSpan.FromMilliseconds(500), TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(1)));
                
                epCfg.ConfigureSagas(context);
            });
        });
    });
});

OrderPMState 工作正常,但 CsaLoginPMState 在触发时会出现以下错误: System.InvalidOperationException:实体类型 CsaLoginPMState 不是当前上下文模型的一部分。

如果我注释掉 OrderPMState 的注册,则 CsaLoginPMState 工作正常。我怀疑,这两个传奇正在使用相同的 DbContext,尽管已注册到各自的 DbContext。

OrderStateDbContext

public class OrderStateDbContext : SagaDbContext
{
    public OrderStateDbContext(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {
    }

    protected override IEnumerable<ISagaClassMap> Configurations
    {
        get { yield return new OrderPMStateMapping(); }
    }
}

CsaLoginStateDbContext

public class CsaLoginStateDbContext : SagaDbContext
{
    public CsaLoginStateDbContext(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {
    }

    protected override IEnumerable<ISagaClassMap> Configurations
    {
        get { yield return new CsaLoginPMStateMapping(); }
    }
}

旧版本的应用程序使用AutoFac,注册是这样完成的:

builder.Register(x =>
    EntityFrameworkSagaRepository<OrderPMState>.CreateOptimistic(() => new OrderStateDbContext(_configuration.GetConnectionString("DB"))))
    .As<ISagaRepository<OrderPMState>>().SingleInstance();

builder.Register(x =>
    EntityFrameworkSagaRepository<CsaLoginPMState>.CreateOptimistic(() => new CsaLoginStateDbContext(_configuration.GetConnectionString("DB"))))
    .As<ISagaRepository<CsaLoginPMState>>().SingleInstance();

我错过了什么吗?

entity-framework masstransit saga
2个回答
0
投票

使用

DbContext
时,您应该使用专门设计用于
DbContext
的两种配置方法之一。

 busCfg.AddSagaStateMachine<CsaLoginPM, CsaLoginPMState>()
    .EntityFrameworkRepository<CsaLoginPMState>(efConfig =>
    {
        efConfig.ConcurrencyMode = ConcurrencyMode.Optimistic;

        efConfig.AddDbContext<DbContext, CsaLoginStateDbContext>((provider,builder) =>
        {
            builder.UseSqlServer(configuration.GetConnectionString("DB"), m =>
            {
                m.MigrationsAssembly(Assembly.GetExecutingAssembly().GetName().Name);
                m.MigrationsHistoryTable($"__{nameof(CsaLoginStateDbContext)}");
            });
        });
    });

或者您可以单独添加 DbContext 并在传奇中使用现有的 DbContext:


services.AddDbContext<CsaLoginStateDbContext>(builder =>
    builder.UseSqlServer(configuration.GetConnectionString("DB"), m =>
    {
        m.MigrationsAssembly(Assembly.GetExecutingAssembly().GetName().Name);
        m.MigrationsHistoryTable($"__{nameof(CsaLoginStateDbContext)}");
    }));

services.AddMassTransit(x =>
{
    x.AddSagaRepository<JobSaga>()
        .EntityFrameworkRepository(r =>
        {
            r.ConcurrencyMode = ConcurrencyMode.Optimistic;
            r.ExistingDbContext<CsaLoginStateDbContext>();
        });
});

这一切都在文档中涵盖了。


0
投票
我在 Entity Framework Core 中遇到了这个问题,并认为我应该与多个 saga 注册共享我的工作代码。关键部分是

AddDbContext

 调用不能同时使用第一个类型参数 
DbContext
 进行多次调用。它需要不同,以便加载正确的模型。

CS

x.AddSagaStateMachine<FirstSagaStateMachine, FirstSaga>() .EntityFrameworkRepository(r => { r.ConcurrencyMode = MassTransit.ConcurrencyMode.Pessimistic; r.AddDbContext<FirstSagaDbContext, FirstSagaDbContext>((_, optionsBuilder) => optionsBuilder.UseSqlServer(connectionString)); }); x.AddSagaStateMachine<SecondSagaStateMachine, SecondSaga>() .EntityFrameworkRepository(r => { r.ConcurrencyMode = MassTransit.ConcurrencyMode.Pessimistic; r.AddDbContext<SecondSagaDbContext, SecondDbContext>((_, optionsBuilder) => optionsBuilder.UseSqlServer(connectionString)); });
    
© www.soinside.com 2019 - 2024. All rights reserved.