How implement the Open Session in View pattern in

2019-02-27 17:37发布

问题:

I'm using ASP.NET MVC + NHibernate + Fluent NHibernate and having a problem with lazy loading.

Through this question (How to fix a NHibernate lazy loading error "no session or session was closed"?), I've discovered that I have to implement the Open Session in View pattern , but I don't know how.

In my repositories classes, I use methods like this

    public ImageGallery GetById(int id) {
        using(ISession session = NHibernateSessionFactory.OpenSession()) {
            return session.Get<ImageGallery>(id);
        }
    }

    public void Add(ImageGallery imageGallery) {
        using(ISession session = NHibernateSessionFactory.OpenSession()) {
            using(ITransaction transaction = session.BeginTransaction()) {
                session.Save(imageGallery);
                transaction.Commit();
            }
        }
    }

And this is my Session Factory helper class:

public class NHibernateSessionFactory {
    private static ISessionFactory _sessionFactory;
    private static ISessionFactory SessionFactory {
        get {
            if(_sessionFactory == null) {
                _sessionFactory = Fluently.Configure()
                    .Database(MySQLConfiguration.Standard.ConnectionString(MyConnString))
                    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<ImageGalleryMap>())
                    .ExposeConfiguration(c => c.Properties.Add("hbm2ddl.keywords", "none"))
                    .BuildSessionFactory();
            }
            return _sessionFactory;
        }
    }
    public static ISession OpenSession() {
        return SessionFactory.OpenSession();
    }
}

Someone could help me to implements Open Session in View pattern?

Thank you.

回答1:

This is already asked before, but I don't remember where to find it. When you do the following or something similar, you have what you want and some code duplication reduce in your repositories as bonus.

  • Use this (code from question modified with the answer) in global.asax: Application_EndRequest Doesn't Fire on a 404
  • Use the same session and transaction instance for every method executed during a web-request.

 

public class Repository
{
  private readonly ISession session;

  public Repository()
  {
    session = CurrentSessionContext.CurrentSession();
  } 

  public ImageGallery GetById(int id) 
  {
    return session.Get<ImageGallery>(id);
  }

  public void Add(ImageGallery imageGallery)
  {
    session.Save(imageGallery);
  }
}

You can also manage the session with an ioc container and a unit of work wrapper instead of the current session context.