我正在努力将旧应用程序移植到 .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();
我错过了什么吗?
使用
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>();
});
});
这一切都在文档中涵盖了。
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));
});