rossisdead
rossisdead

Reputation: 2108

Lazy Loaded NHibernate entities in MVC3 views

We're having an issue where I work. When we try to access a lazy loaded property on an NHibernate entity from within an MVC3 view, a "No Session" LazyInitializationException will be thrown. This only started cropping up on us in the last week, but we've been unable to narrow down the problem. There doesn't look like there's a simple solution though.

Notes:

What are we missing here?

Upvotes: 1

Views: 668

Answers (2)

0lukasz0
0lukasz0

Reputation: 3267

Your entity loading pattern is called open session in view and it is considered an anti-pattern. More on cons of this pattern here and here.

The recommended approach would be using some view models with pre-fetched data. But if you can't do it, you could pre-fetch model data using linq to nhibernate expand extension. There is an open-source library ITDT.Sentia, which provides typed expand extension or you can search for "nhibernate expand" in google. For more low level thing you can have a look at nhibernate fetching strategies.

For instance using ITDT.Sentia library and having following models:

public class User : BaseEntity
{
    public virtual string Email { get; set; }
    public virtual Company Company { get; set; }
}

public class Company : BaseEntity
{
    public virtual string Name { get; set; }
}

And assuming lazy loading of Company entity after fetching user, you can do something like:

IList<User> users = userRepository
  .GetAll()
  .Where(u => /*some constraints*/)
 // here you are telling nhibernate to make a join and eger load what you need
  .Expand(u  => u.Company) 
  .ToList();

As for different behavior in dev-environment I can only guess that somehow it is using some other configuration files, maybe there are different debug/release web.configs?

Upvotes: 1

Fran
Fran

Reputation: 6520

Are you binding directly to your object model in your views? That sounds like your problem in that you view binds directly to a domain object. Since the domain object has lazy collections it is trying to then load the collection elements on demand, which need an Nhibernate session.

You should be building up your complete view model in your controller method.

my suggestion would be to create a view model for each view that you have. Then when you are querying NHibernate, project directly into the model or use Automapper to convert your object model into the view model. The nice thing about direct projection is that the query through nhibernate will be more efficient because it will only select the columns you need.

Also see this article. http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

it's a create set of best practices for view models.

Upvotes: 0

Related Questions