2009-12-01 6 views
1

J'ai une base de données héritée où une proc stockée calcule les identifiants de ligne pour toutes les tables. Maintenant, je veux remplacer le IIdentifierGenerator comme indiqué à cette page http://www.richter-web.info/Wordpress/?p=132 juste pour éviter l'Id (x => x.id) .GenereatedBy.Assigned.NHibernate extrait DBTransaction de la session

Maintenant que je sauve un objet, bien sûr à l'intérieur d'une transaction Nhibernate, nommée AppendixHierarchy, puis dès qu'elle pénètre dans ATKIdGenerator.Generate et il commence command.ExecuteNonQuery() Je reçois une exception ExecuteNonQuery nécessite la commande d'avoir une transaction lorsque la connexion affectée à la commande est dans une transaction locale en attente. La propriété Transaction de la commande n'a pas été initialisée.

Comment puis-je extraire la transaction DB de l'objet de session Nhibernate, afin de l'attacher à la commande?

J'ai utilisé le FluentMapping pour le poco

public AppendixHierarchyMap() 
     { 
      Table("appendixHierarchy"); 
      Id(x => x.id).GeneratedBy.Custom(typeof(ATKIdGenerator), a => a.AddParam("TableName", "appendixHierarchy")); 
..... 

Et voici le Id Générateur

public class ATKIdGenerator : IIdentifierGenerator, IConfigurable 
    { 

     private string TableName { get; set; } 
     #region IIdentifierGenerator Members 

     public object Generate(NHibernate.Engine.ISessionImplementor session, object obj) 
     { 
      IDbCommand command = new SqlCommand(); 
      command.Connection = session.Connection; 
      //transaction.Enlist(command); 
      command.CommandType = CommandType.StoredProcedure; 
      command.CommandText = "dbo.ups_GetNewId"; 
      // Set input parameters 
      var parm = new SqlParameter("@tableName", SqlDbType.VarChar); 
      parm.Value = TableName; 
      command.Parameters.Add(parm); 
      // Set output parameter 
      var outputParameter = new SqlParameter("@id", SqlDbType.Int); 
      outputParameter.Direction = ParameterDirection.Output; 
      command.Parameters.Add(outputParameter); 
      // Set a return value 
      var returnParameter = new SqlParameter("@RETURN_VALUE", SqlDbType.Int); 
      returnParameter.Direction = ParameterDirection.ReturnValue; 
      command.Parameters.Add(returnParameter); 
      // Execute the stored procedure 
      command.ExecuteNonQuery(); 
      return (int)((SqlParameter)command.Parameters["@id"]).Value;  
     } 

     #endregion 

     #region IConfigurable Members 

     public void Configure(NHibernate.Type.IType type, IDictionary<string, string> parms, NHibernate.Dialect.Dialect d) 
     { 
      TableName = parms["TableName"]; 
     } 

     #endregion 
    } 

Répondre

1

Je pense que vous avez besoin d'ouvrir une autre connexion à générer la méthode plutôt que de réutiliser un sur la session.

+0

Cela fonctionne essentiellement. mais c'est lent en quelque sorte. Avant que j'appelle Enregistrer de toute entité, il appelle le Générer, puis il faut 60 secondes avant d'appliquer les insertions réelles de l'entité .... Ceci est trop lent ... – urpcor

Questions connexes