I have been putting off this question for some time but now it is bothering me all the time. I have 2 classes (These classes are automapped – I leave out public and virtual for brevity.):
class Cashier
{
int Id {get; set;}
string name{get; set;}
IList<Site> Sites {get; set;}
}
class Site
{
int Id{get; set;}
string name {get; set;}
Cashier Cashier {get; set;}
}
I load cashiers with this :
sealed class Repository<T> : IRepository<T> where T :class
{
public IList<T> Items { get; private set; }
public void Load()
{
Items.Clear();
var session = SessionHelper.GetSession();
session.Clear();
using (var tx = session.BeginTransaction())
{
var list = session.Query<T>().ToList();
foreach (var obj in list)
{
Items.Add((T)session.Merge(obj));
}
session.Clear();
tx.Commit();
}
}
//more
}
and in a winform i bind it to a bindingsource like this:
cashierBindingSource.DataSource = Cashiers;
I set this bindingsource as the data source of a combobox and when I run the application and click on the combobox this exception is thrown at me :
Initializing[HRProject.Model.Cashier#1]-failed to lazily initialize a collection of role: HRProject.Model.Cashier.Sites, no session or session was closed
I found that providing a mapping override fixes this problem
mapping.HasMany(x => x.Sites).Not.LazyLoad().Cascade.All();
However, I have many such classes and I get the feeling there’s a cleaner way to get this done. Any ideas?
In my experience, FNH, WinForms data binding, and lazy loading are a difficult mix.
If you need lazy loading, you need to keep a session open for the life of the form.
If you don’t need it, you can turn it off.
The easiest way I’ve found to do this for a whole project is to use the DefaultLazy convention:
Go to “The Simplest Conventions” section on the wiki, for this, and a list of others.
Here’s the list from the Wiki:
A word of warning – some of the method names in the Wiki may be wrong. I edited the Wiki with what I could verify (i.e. DefaultCascade and DefaultLazy), but can’t vouch for the rest. But you should be able to figure out the proper names with Intellisense if the need arises.