1

La transaction spécifiée n'est pas associée à la connexion en cours. Seules les transactions associées à la connexion en cours peuvent être utilisées.ABP EF Plusieurs accès DbContext dans IDomainService génère une erreur de transaction

Comment utiliser plusieurs DbContext dans une transaction?

Mise à jour 1

Si je ExistingConnection, alors tous les DbContext utiliseront la même chaîne de connexion. Est-ce que j'ai ajouté plusieurs DbContext dans le mauvais sens?

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

Mise à jour 2

je suis arrivé à travailler en mettant en place IConnectionStringResolver pour les connexions personnalisées:

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

Ne pas oublier de remplacer le service dans PreInitialize méthode de EntityFrameworkModule :

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

il est maintenant le travail, le code dans https://github.com/BivoZeou/ABPCore – Bivozeou

Répondre

3

Ajouter ceci dans *DbContextConfigurer.cs:

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

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

Référence: https://github.com/aspnetboilerplate/module-zero-core-template/commit/da522e76ca2ecefdb7670f009f78575c5b97b4a0


Important

Si chaque DbContext a sa propre chaîne de connexion, vous devez mettre en œuvre IConnectionStringResolver comme expliqué here et remplacer le service:

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

si i USD connexion existante , le multiple dbcontext utilisera une chaîne de connexion, il lancera SqlException: Nom d'objet invalide 'tablexxx', est-ce que j'ajoute plusieurs dbcontext dans le mauvais sens? j'ajoute dbcontext à EntityFrameworkModule, PreInitialize – Bivozeou

+0

je suis sûr quand je débogue, connexion existante est même, mon code dans https://github.com/BivoZeou/ABPCore ici vous pouvez voir – Bivozeou

+0

Pouvez-vous implémenter et remplacer 'IConnectionStringResolver' comme expliqué [ici] (https://github.com/aspnetboilerplate/aspnetboilerplate/pull/1834#issuecomment-326041970)? Vous avez le même problème que [this] (https://github.com/aspnetboilerplate/aspnetboilerplate/issues/2325). – aaron