I am using NHibernate's QueryOver to populate an IEnumerable of a class that has many nested classes. However, this is yielding a lot separate select statements in Sql Profiler. Using the example below, NHibernate selects results from the foo table, then "loops" through each row in the result set, selecting from bar, foobar, etc. Ideally, I would like for this to be one select statement using joins, but I'm not sure if that's possible.
I think the problem may lie with the Not.LazyLoad() methods in the mappings.
Given these classes and mappings:
public class Foo
{
public virtual int FooId {get; set;}
public virtual Bar Bar {get; set;}
public virtual Baz Baz {get; set;}
}
public class Bar
{
public virtual int BarId {get; set;}
public virtual FooBar FooBar {get; set;}
...
}
public class FooMap : ClassMap<Foo>{
public FooMap(){
Schema("my_schema");
Table("foo");
LazyLoad();
Id(x => x.FooId).GeneratedBy.Identity().Column("foo_id");
References(x => x.Bar).Column("bar").Not.LazyLoad();
References(x => x.Baz).Column("baz").Not.LazyLoad();
}
}
public class BarMap : ClassMap<Bar>{
public BarMap(){
Schema("my_schema");
Table("bar");
LazyLoad();
Id(x => x.FooId).GeneratedBy.Identity().Column("bar_id");
References(x => x.FooBar).Column("foo_bar").Not.LazyLoad();
}
}
I am using queryover in the following way to populate the IEnumerable:
IEnumerable<Foo> foos;
using (ISession session = NHibernateSessionFactoryManager.Factory.OpenSession())
{
foos = session.QueryOver<foos>()
.Where(f => f.Baz.BazId == bazId).List();
}
And here's my NHibernateSesssionFactory Manager class:
public class NHibernateSessionFactoryManager {
private static readonly Object lockObject = new object();
private static readonly ISessionFactory SessionFactory = BuildSessionFactory();
private static ISessionFactory BuildSessionFactory(){
lock (lockObject){//make sure only one session factory is created per start of the app
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(c => c
.FromConnectionStringWithKey("foobardb")))
.Mappings(m =>
m.FluentMappings.AddFromAssemblyOf<FooMap>())
//.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
}
private static void BuildSchema(Configuration config) {
// export the database schema
new SchemaExport(config)
.Create(true,false);
}
public static ISession OpenSession(){
return Factory.OpenSession();
}
public static ISessionFactory Factory{
get{
return SessionFactory;
}
}
}