I have a table Parent and a table Child. Child contains a foreign-key to the Parent table, creating a one-to-many relationship. Here is a part of my mapping that I define with fluent NHibernate:
public class ParentMap : ClassMap<Parent> { public ParentMap() { WithTable("Parents"); Id(x => x.Id, "ParentID") .WithUnsavedValue(0) .GeneratedBy.Identity(); Map(x => x.Description, "Description"); HasMany<Child>(x => x.Childs) .LazyLoad() .WithKeyColumn("ParentID") .IsInverse() .AsSet(); } } public class ChildMap : ClassMap<Child> { public ChildMap() { WithTable("Childs"); Id(x => x.Id, "ChildID") .WithUnsavedValue(0) .GeneratedBy.Identity(); References(x => x.Parent, "ParentID") .CanNotBeNull() .LazyLoad(); } }
As you can see I have set LazyLoad on the relation. Note also that in my model classes, all properties are set as virtual.
Now for the simple query:
ICriteria crit = Session.CreateCriteria(typeof(Child)) .Add(Expression.Eq("Id", 18)); IList<Child> list = crit.List<Child>();
And the SQL generated:
SELECT this_.ChildID as ChildID5_1_, this_.ParentID as ParentID5_1_, parent2_.ParentID as ParentID4_0_, parent2_.Description as Descript2_4_0_ FROM Childs this_ inner join Parents parent2_ on this_.ParentID = parent2_.ParentID WHERE this_.ChildID = 18 /* @p0 */
As you can see, it does a join on the Parent table and selects its fields (id and description). But why does it do that since I requested lazyloading ?
Now if I change the query to:
ICriteria crit2 = Session.CreateCriteria(typeof(Child)) .SetFetchMode("Parent", FetchMode.Lazy) .Add(Expression.Eq("Id", 18));
There are 2 sql queries generated:
SELECT this_.ChildID as ChildID5_0_, this_.ParentID as ParentID5_0_ FROM Childs this_ WHERE this_.ChildID = 18 /* @p0 */
which is good to me: no join, the Parent table is not queried. But I get this second one too:
SELECT parent0_.ParentID as ParentID4_0_, parent0_.Description as Descript2_4_0_ FROM Parents parent0_ WHERE parent0_.ParentID = 45 /* @p0 */
which again queries the Parent table.
These 2 queries are generated during the line:
IList<Child> list = crit.List<Child>();
I'm totally ignorant of what happens here. Can someone help?