ISession + NHibernate (no session or session was closed)

0

In a WindowsForms project

Using standard repository, in a generic class I have the following method:

    public IList<T> Listar() {
        using (ISession session = SessionFactory.Instance.GetSession()) {
            return (from c in session.Query<T>() select c).ToList();
        }
    }

It works normally and closes the session (I guess it's the right way).

I load the result into a datagridview and when I try to access more complex objects (with reference to other classes) I get the exception no session or session was closed , since I'm using LazyLoad by default.

Is there any way around this problem, considering keeping LazyLoad?

Singleton of SessionFactory, which always returns a new session

public class SessionFactory {
    public string ConnectionString { get; set; }

    /// <summary>
    /// Instancia da classe SessionFactory
    /// </summary>
    private static SessionFactory _instance;
    private SessionFactory() {
    }
    public static SessionFactory Instance {
        get {
            return _instance ?? (_instance = new SessionFactory());
        }
    }

    /// <summary>
    /// Instancia singleton de objeto do tipo ISessionFactroy
    /// </summary>
    private ISessionFactory _sessionFactory;
    private ISessionFactory GetSessionFactory {
        get {
            return _sessionFactory ?? (_sessionFactory = BuildFactory());
        }
    }

    /// <summary>
    /// Método que retorna objeto ISessionFactory
    /// </summary>
    /// <returns></returns>
    private ISessionFactory BuildFactory() {
        try {
            IPersistenceConfigurer configDB = PostgreSQLConfiguration
                    .PostgreSQL82
                    .ConnectionString(ConnectionString)
                    .ShowSql()
                    .FormatSql()
                    .UseReflectionOptimizer();

            FluentConfiguration FConf = Fluently.Configure()
                .Database(configDB)
                .Mappings(c => c.FluentMappings.AddFromAssemblyOf<System.Retaguarda.Map.UsuarioMap>())
                .ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(false, true));

            return FConf.BuildSessionFactory();
        } catch (Exception ex) {
            Console.WriteLine("Erro ao carregar configurações do banco de dados\nDica: Verifique as configurações de conexão\n" + ex.Message + "\n" + ex.InnerException);
            throw ex;
        }
    }

    public ISession GetSession() {
        return GetSessionFactory.OpenSession();
    }

}
    
asked by anonymous 17.01.2017 / 14:12

1 answer

0

I used the IDisposable interface and I'm handling the session on form:

Repository:

public class Repository<T> : IDisposable, IRepository<T> where T : class {
    protected ISession session = SessionFactory.Instance.GetSession();

    public void Gravar(T entidade) {
        using (ITransaction transacao = session.BeginTransaction()) {
        }
    }

    public void Excluir(T entidade) {
        using (ITransaction transacao = session.BeginTransaction()) {
        }
    }

    public T PesquisarPorId(int Id) {
        return session.Get<T>(Id);
    }

    public IList<T> Listar() {
        return (from c in session.Query<T>() select c).ToList();
    }

    public void Dispose() {
        session.Close();
    }
}

Form:

    private void PanelCrud_Disposed(object sender, EventArgs e) {
        IDisposable disposable = Repositorio as IDisposable;
        if (disposable != null)
            disposable.Dispose();
    }

In this way, I have a singleton SessionFactory and for each form I start a session that will be closed in the event Dispose ()

    
21.01.2017 / 13:25