当前位置:  开发笔记 > 编程语言 > 正文

NHibernate:无法成功设置延迟加载

如何解决《NHibernate:无法成功设置延迟加载》经验,为你挑选了1个好方法。

我有一个表Parent和一个表Child.Child包含Parent表的外键,创建一对多关系.这是我使用流畅的NHibernate定义的映射的一部分:

public class ParentMap : ClassMap
{
    public ParentMap()
    {
        WithTable("Parents");

        Id(x => x.Id, "ParentID")
        .WithUnsavedValue(0)
        .GeneratedBy.Identity();

        Map(x => x.Description, "Description");

        HasMany(x => x.Childs)
        .LazyLoad()
        .WithKeyColumn("ParentID")
        .IsInverse()
        .AsSet();
    }
}

public class ChildMap : ClassMap
{
    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 list = crit.List();

并生成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 */

如您所见,它在Parent表上进行连接并选择其字段(id和description).但是,为什么我要求延迟加载呢?

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

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

它再次查询父表.

这两行查询是在行中生成的:

IList list = crit.List();

我完全不知道这里发生了什么.有人可以帮忙吗?



1> James Gregor..:

这取决于您的Fluent NHibernate版本.直到某个点为止,默认情况下所有实体都不会延迟加载.这相当于lazy="false"在您的实体中明确设置.现在不再是这种情况了,但是如果你在那之前运行任何事情,那么你会看到这种行为.

多对一/引用延迟加载设置被来自目标的实体级延迟加载覆盖,因此如果您在此旧版本的FNH上运行,则实体设置将使您的References(...).LazyLoad()调用无意义.

您需要验证您是否使用最新版本的FNH,这应该可以解决问题; 但是,如果没有,那么您需要在Parent实体中明确设置延迟加载.你可以用上面的LazyLoad方法做到这一点ClassMap.

推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有