NHibernate: can't successfully set lazy loading

匿名 (未验证) 提交于 2019-12-03 02:29:01

问题:

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?

回答1:

It'll depend on your version of Fluent NHibernate. Up until a certain point it was the default that all entities would not be lazy loaded. This is the equivalent of explicitly setting lazy="false" in your entity. This is no longer the case, but if you are running on anything prior to that point then you'll see this behaviour.

The many-to-one/references lazy load setting gets overridden by the entity level lazy load from the target, so if you are running on this older version of FNH then the entity setting will be rendering your References(...).LazyLoad() call moot.

You need to verify you're on the latest version of FNH, that should fix things; however, if it doesn't then you need to explicitly set lazy loading on in your Parent entity. You can do that with the LazyLoad method on the ClassMap<T>.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!