Base solution for your next web application
Open Closed

Sharing transaction among EF Core contexts #3640


User avatar
0
henriksorensen created

Hi

We have to access and update tables in two databases within same transaction scope. We have the same setup as described here, <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/issues/2325">https://github.com/aspnetboilerplate/as ... ssues/2325</a>. Also we have changed database transaction strategy to DbContextEfTransactionStrategy as described in <a class="postlink" href="https://aspnetboilerplate.com/Pages/Documents/EntityFramework-Integration#transaction-management">https://aspnetboilerplate.com/Pages/Doc ... management</a>.

The metod public DbContext CreateDbContext<TDbContext>(string connectionString, IDbContextResolver dbContextResolver) is always called the default connectionstring and therefore the second dbcontext is never inserted into this.ActiveTransactions[connectionString].

Abp Version is 2.2.2

Regards,


3 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @henriksorensen,

    Can you share your code for configuring your dbContexes in your EF Core module ?

    Thanks.

  • User Avatar
    0
    henriksorensen created
    1. DbContext: public class SchemaStagingServiceDbContext : AbpZeroDbContext<Tenant, Role, User, SchemaStagingServiceDbContext> { public virtual DbSet<Schema> Schemas { get; set; } public SchemaStagingServiceDbContext(DbContextOptions<SchemaStagingServiceDbContext> options) : base(options) { } }

    Add and configure DbContext in SchemaStagingServiceEntityFrameworkCoreModule public override void PreInitialize() { Configuration.ReplaceService<IEfCoreTransactionStrategy, DbContextEfCoreTransactionStrategy>(DependencyLifeStyle.Transient); if (!SkipDbContextRegistration) { Configuration.Modules.AbpEfCore().AddDbContext<SchemaStagingServiceDbContext>(configuration => { SchemaStagingServiceDbContextConfigurer.Configure(configuration.DbContextOptions, configuration.ConnectionString); }); } }

    1. DbContext: public class StagingDbContext : AbpDbContext { public virtual DbSet<Schemadata> Schemadata { get; set; } public StagingDbContext(DbContextOptions<StagingDbContext> options) : base(options) { } }

    Add and configure DbContext in StagingInfrastructureModule public override void PreInitialize() { Configuration.ReplaceService<IEfCoreTransactionStrategy, DbContextEfCoreTransactionStrategy>(DependencyLifeStyle.Transient); if (!SkipDbContextRegistration) { Configuration.Modules.AbpEfCore().AddDbContext<StagingDbContext>(configuration => { StagingDbContextConfigurer.Configure(configuration.DbContextOptions, "Server=localhost; Database=Staging; Trusted_Connection=True; MultipleActiveResultSets=True;"); }); } }

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    In your case, you need to implement a custom connection string resolver. It is better to derive one from DefaultConnectionStringResolver (<a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/blob/master/src/Abp/Domain/Uow/DefaultConnectionStringResolver.cs">https://github.com/aspnetboilerplate/as ... esolver.cs</a>) and override GetNameOrConnectionString method.

    In that method, return correct connection string for your second dbContext by checking dbContextType from ConnectionStringResolveArgs.

    Of course, you need to replace IConnectionString resolver with your implementation in dependency injection by using ABP's replace service extension method.

    Thanks.