3
votes

The specified transaction is not associated with the current connection. Only transactions associated with the current connection may be used.

How do I use multiple DbContext in one transaction?

Update 1

If I use ExistingConnection, then all the DbContext will use the same connection string.

Did I add multiple DbContext in the wrong way?

In EntityFrameworkModule:

public override void PreInitialize()
{
    var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());

    Configuration.Modules.AbpEfCore().AddDbContext<BPDbContext>(options =>
    {
        if (options.ExistingConnection != null)
        {
            options.DbContextOptions.UseSqlServer(options.ExistingConnection);
        }
        else
        {
            options.DbContextOptions.UseSqlServer(configuration.GetConnectionString(ABPCoreConsts.BPConnectionStringName));
        }

        //options.DbContextOptions.UseSqlServer(
        //    configuration.GetConnectionString(ABPCoreConsts.BPConnectionStringName));
    });

    Configuration.Modules.AbpEfCore().AddDbContext<EPlusDBConext>(options =>
    {
        if (options.ExistingConnection != null)
        {
            options.DbContextOptions.UseSqlServer(options.ExistingConnection);
        }
        else
        {
            options.DbContextOptions.UseSqlServer(configuration.GetConnectionString(ABPCoreConsts.EECPlusConnectionStringName));
        }

        //options.DbContextOptions.UseSqlServer(
        //    configuration.GetConnectionString(ABPCoreConsts.EECPlusConnectionStringName));
    });

    Configuration.Modules.AbpEfCore().AddDbContext<ProjectManageDbContext>(options =>
    {
        if (options.ExistingConnection != null)
        {
            options.DbContextOptions.UseSqlServer(options.ExistingConnection);
        }
        else
        {
            options.DbContextOptions.UseSqlServer(configuration.GetConnectionString(ABPCoreConsts.PMConnectionStringName));
        }

        //options.DbContextOptions.UseSqlServer(
        //    configuration.GetConnectionString(ABPCoreConsts.PMConnectionStringName));
    });

    RegisterGenericRepositories();
}

Update 2

I got it to work by implementing IConnectionStringResolver for custom connections:

public class MyDBConnectionStringResolver : DefaultConnectionStringResolver
{
    public override string GetNameOrConnectionString(ConnectionStringResolveArgs args)
    {
        var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());

        switch (args["DbContextType"].ToString())
        {
            case "ABPCore.EPlusDBConext":
                return configuration.GetConnectionString(ABPCoreConsts.EECPlusConnectionStringName);
            case "ABPCore.BPDbContext":
                return configuration.GetConnectionString(ABPCoreConsts.BPConnectionStringName);
            case "ABPCore.ProjectManageDbContext":
                return configuration.GetConnectionString(ABPCoreConsts.PMConnectionStringName);
        }

        return string.Empty;
    }
}

Don't forget to replace service in EntityFrameworkModule's PreInitialize method:

Configuration.ReplaceService<IConnectionStringResolver, MyDbConnectionStringResolver>(DependencyLifeStyle.Transient);
1
it's work now ,code in github.com/BivoZeou/ABPCore - Bivozeou

1 Answers

4
votes

Add this in *DbContextConfigurer.cs:

public static void Configure(DbContextOptionsBuilder<*DbContext> builder, DbConnection connection)
{
    builder.UseSqlServer(connection);
}

Change this in *EntityFrameworkModule.cs:

public override void PreInitialize()
{
    if (!SkipDbContextRegistration)
    {
        Configuration.Modules.AbpEfCore().AddDbContext<*DbContext>(options =>
        {
            if (options.ExistingConnection != null)
            {
                options.DbContextOptions.UseSqlServer(options.ExistingConnection);
            }
            else
            {
                options.DbContextOptions.UseSqlServer(options.ConnectionString);
            }
        });
    }
}

Reference: https://github.com/aspnetboilerplate/module-zero-core-template/commit/da522e76ca2ecefdb7670f009f78575c5b97b4a0


Important

If each DbContext has its own connection string, you need to implement IConnectionStringResolver as explained here and replace the service:

Configuration.ReplaceService<IConnectionStringResolver, MyConnectionStringResolver>(DependencyLifeStyle.Transient);