IDomainService中的ABP EF Core多个DbContext访问会引发事务错误

时间:2017-10-11 09:46:08

标签: entity-framework asp.net-core transactions dbcontext aspnetboilerplate

  

指定的事务与当前连接无关。只能使用与当前连接关联的事务。

如何在一个事务中使用多个DbContext?

更新1

如果我使用ExistingConnection, 那么所有DbContext都将使用相同的连接字符串。

我是否以错误的方式添加了多个DbContext?

在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();
}

更新2

我通过为自定义连接实现IConnectionStringResolver来实现它:

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;
    }
}

不要忘记在EntityFrameworkModule的PreInitialize方法中替换服务:

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

1 个答案:

答案 0 :(得分:3)

*DbContextConfigurer.cs

中添加此内容
public static void Configure(DbContextOptionsBuilder<*DbContext> builder, DbConnection connection)
{
    builder.UseSqlServer(connection);
}

*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);
            }
        });
    }
}

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

重要

如果每个DbContext都有自己的连接字符串,则需要按照here的说明实施IConnectionStringResolver并替换服务:

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