我有一个表父和表儿童。子含有外键的父表,创建一个一对多的关系。这是我的映射的一部分,我与功能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();
    }
}

正如你可以看到我已经设置LazyLoad上的关系。还要注意的是在我的模型类,所有属性被设定为虚拟的。

现在的简单查询:

ICriteria crit = Session.CreateCriteria(typeof(Child))
    .Add(Expression.Eq("Id", 18));
IList<Child> list = crit.List<Child>();

和SQL生成:

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 */

可以看到,但它一对母表加入和选择其字段(ID和说明)。但是,为什么会这样,因为我要求的惰性加载?

现在,如果我查询更改为:

ICriteria crit2 = Session.CreateCriteria(typeof(Child))
    .SetFetchMode("Parent", FetchMode.Lazy)
    .Add(Expression.Eq("Id", 18));

有产生2个SQL查询:

SELECT this_.ChildID  as ChildID5_0_,
       this_.ParentID as ParentID5_0_
FROM   Childs this_
WHERE  this_.ChildID = 18 /* @p0 */

这是很好的对我说:不加入,父表中没有查询。 但是,我得到这个第二个太:

SELECT parent0_.ParentID    as ParentID4_0_,
       parent0_.Description as Descript2_4_0_
FROM   Parents parent0_
WHERE  parent0_.ParentID = 45 /* @p0 */

其再次查询父表。

这2个查询行期间产生的:

IList<Child> list = crit.List<Child>();

我一无所知的东西在这里发生。有人可以帮忙吗?

有帮助吗?

解决方案

这将取决于你的功能NHibernate的版本。直到某一点它是默认的,所有的实体将的的懒惰加载。这是在实体明确设置lazy="false"相当。这已不再是这样,但如果你是在此之前,任何点运行,然后你会看到这一行为。

在许多到一/引用延迟加载设置被从目标实体层面延迟加载重写,所以如果你在这个旧版本FNH的运行,那么实体设置将渲染你References(...).LazyLoad()电话没有实际意义。

您需要验证你在最新版本的FNH,应该解决的事情;但是,如果没有的话,你需要明确设置延迟加载在你Parent实体。你可以做到这一点与上LazyLoadClassMap<T>方法。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top