【问题标题】:Explain Eagar loading and Lazy loading in NHibernate解释 NHibernate 中的 Eagar 加载和延迟加载
【发布时间】:2014-01-09 14:21:17
【问题描述】:

在实体框架中,我们可以使用“include”来实现预先加载。我已经为 NHibernate linq 中的 eagar 加载编写了以下查询。

IList empl = Session.CreateCriteria(typeof(Employee))
                      .Add(Expression.Like("Name", "Pete%"))
                      .SetFetchMode("Name", FetchMode.Eager)
                      .SetFetchMode("Desigantion", FetchMode.Eager)
                      .List();

谁能给我一个更好的例子来说明 NHibernate Linq 中的 eagar 和延迟加载。我在流利的 Nhibernate 中有以下映射:

Table("DEMO_Employee");
            Id(t => t.Id).Column("Id").GeneratedBy.Identity();
            Map(t => t.Name, "Name");
            Map(t => t.Designation, "Designation");
            Map(t => t.Gender, "Gender");
            Map(t => t.Age, "Age");
            Map(t => t.Enabled, "Enabled");
            Map(t => t.CreatedById).Column("CreatedBy");
            Map(t => t.LastModifiedById).Column("LastModifiedBy").Nullable();
            Map(t => t.IsDeleted).Column("IsDeleted");
            Map(t => t.CreatedDate).Column("CreatedDate");
            Map(t => t.LastModifiedDate).Column("LastModifiedDate").Nullable();
            References(x => x.Department).ForeignKey("DeptId"); 



Table("DEMO_Department");
            Id(t => t.DeptId).Column("DeptId").GeneratedBy.Identity();
            Map(t => t.DeptName, "DeptName");
            Map(t => t.Enabled, "IsEnable");

【问题讨论】:

    标签: asp.net-mvc linq nhibernate fluent-nhibernate


    【解决方案1】:

    看看19.1.2. Tuning fetch strategies,一个引用:

    通常,我们不使用映射文档来自定义提取。相反,我们保留默认行为,并在 HQL 中使用 left join fetch 为特定事务覆盖它。这告诉 NHibernate 在第一个选择中使用外连接急切地获取关联。在 ICriteria 查询 API 中,您将使用 SetFetchMode(FetchMode.Join)

    上面的映射和查询不适合。我们不必在值类型属性上使用Fetch。就关系而言。所以,这个.SetFetchMode("Name".. 就不需要了

    所以,在你的映射中

    References(x => x.Department)
    

    是正确的。我们没有指定任何默认的获取策略。我们将其保留为默认(惰性)设置。

    一旦我们开始查询,我们可以通过使用这些特性来改变延迟加载(类似于包含):

    session.CreateCriteria(typeof(Employee))
        // will be part of the SELECT clause... not ready for querying
        .SetFetchMode("Department", FetchMode.Join)
        // if needed for querying ... 
        .CreateCriteria("Department", "Dep", JoinType.LeftOuterJoin)
        // or join alias, which is similar but we are working with the original criteria
        .CreateAlias("Department", "Dep")
    

    所有这些方法都将产生一个 SELECT,将所有结果连接起来。
    请参阅 NHibernate - CreateCriteria vs CreateAlias

    如果我们只查询Employee,所有相关的东西都会被延迟加载

    我想说,除非我们需要相关的东西进行查询(然后使用CreateCriteria),否则我们应该尽可能使用延迟加载。但是为了避免 1 + N 的场景,我们可以使用批处理。这在此处进行了详细描述:19.1.5. Using batch fetching

    要将批处理与流式映射一起使用,您可以像这样标记您的类:

    Table("DEMO_Employee");
    Id(...
    ...
    BatchSize(25);
    

    然后你的相关数据也会被延迟加载,但是是分批加载的。 one-to-many/HasMany(集合)也是如此

    【讨论】:

    • 再次感谢您的回答。其实我想实现eagar加载。您能否通过向我提供任何代码或参考来提供我实现此目标的方法。
    • 请看一下并阅读这篇博文:ayende.com/blog/4367/…。 Ayende 是 NHibernate 的“大师”,所以这些帖子确实有答案。我敢肯定你触及了 15.5 - 动态获取(急切加载)ayende.com/blog/4367/…。因此,请使用 SetFetchMode()CreateAlias()... 急切地加载内容。但是,请尝试观察我给你的链接中的BatchSize。多年来,我确实使用它而不是急切地加载......我更高兴和感激。
    • 感谢您的支持。
    猜你喜欢
    • 1970-01-01
    • 2011-07-16
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    相关资源
    最近更新 更多