2010-08-24 13 views
2

J'ai actuellement une classe NHibernateHelper qui crée une fabrique de sessions. Je continue de recevoir des erreurs en disant 'Session fermée!'. Est-ce que je vais dans le mauvais sens? L'erreur se produit lorsque j'appelle Ajouter (connexion de connexion) qui est appelée après Ajouter (utilisateur utilisateur)Quelle est une bonne façon d'installer les méthodes CRUD et SessionFactory dans Nhibernate?

public class NHibernateHelper 
{ 
    private static ISessionFactory _sessionFactory; 

    private static ISessionFactory SessionFactory 
    { 
     get 
     { 
      if (_sessionFactory == null) 
      { 
       var configuration = new Configuration(); 
       configuration.Configure(); 
       configuration.AddAssembly("System.Core"); 
       _sessionFactory = configuration.BuildSessionFactory(); 
      } 
      return _sessionFactory; 
     } 
    } 

    public static ISession OpenSession() 
    { 
     return SessionFactory.OpenSession(); 
    } 
} 

Voici mon dépôt:

internal class UserRepository : IUserRepository 
{ 
    private ISession _db = NHibernateHelper.OpenSession(); 

    public void Add(User user) 
     { 
      using (_db) 
      { 
       using (ITransaction transaction = _db.BeginTransaction()) 
       { 
        IEnumerable<UserRole> userRoles = user.UserRoles; 
        user.UserRoles = null; 
        _db.Save(user); 
        foreach (UserRole userRole in userRoles) 
        { 
         userRole.UserID = user.UserID; 
         _db.Save(userRole); 
        } 
        transaction.Commit(); 
       } 
      } 
     } 



     public void Add(Login login) 
     { 
      using (_db) 
      { 
       using (ITransaction transaction = _db.BeginTransaction()) 
       { 
        _db.Save(login); 
        transaction.Commit(); 
       } 
      } 

     } 
} 

Répondre

2

Ceci est parce que vous appelez à l'aide (_db) , qui ferme la session à la fin du bloc.

Plutôt que d'avoir la _db variables il suffit d'appeler OpenSession pour chaque opération

public void Add(User user) 
    { 
     using (ISession session = NHibernateHelper.OpenSession()) 
     { 
      using (ITransaction transaction = session.BeginTransaction()) 
      { 
       IEnumerable<UserRole> userRoles = user.UserRoles; 
       user.UserRoles = null; 
       session.Save(user); 
       foreach (UserRole userRole in userRoles) 
       { 
        userRole.UserID = user.UserID; 
        session.Save(userRole); 
       } 
       transaction.Commit(); 
      } 

     } 
    } 

MISE À JOUR:

public void Add(Login login) 
    { 
     using (ISession session = NHibernateHelper.OpenSession()) 
     { 
      Add(login, session); 
     } 
    } 

    public void Add(Login login, ISession session) 
    { 
     //no longer need to create a session here - it is passed in 
     //using (ISession session = NHibernateHelper.OpenSession()) 

     ...Add using the session 
    } 

Il est la création de l'usine qui est cher, donc votre Helper est un bonne chose à utiliser. L'ouverture de la session est une opération bon marché, donc pas besoin d'avoir une session partagée comme celle-ci.

Voici un lien vers une autre question SO qui montre comment rendre votre aide usine threadsafe:

Ensure NHibernate SessionFactory is only created once

+0

En utilisant comme ci-dessus si la volonté qui créent une instance de l'usine pour chaque opération de crud? – Andrew

+0

Non, l'usine est un singleton statique. C'est l'ISession qui sera créée pour chaque opération. Voir mon édition pour la raison que le _db est en cours de fermeture. - Première ligne de ma réponse. –

+0

En outre, vous pouvez tester si une nouvelle usine est créée en mettant un point d'arrêt sur la ligne après: if (_sessionFactory == null) –