在NHibernate中解释Eagar加载和延迟加载

时间:2014-01-09 06:03:07

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

在实体框架中,我们可以使用“include”来实现eagar加载。我在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");

1 个答案:

答案 0 :(得分:1)

看看19.1.2. Tuning fetch strategies,引用:

  

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

上面的映射和查询不适合。我们不必在值类型属性上使用Fetch。只是在关系上。因此,不需要.SetFetchMode("Name"..

所以,在你的映射中

References(x => x.Department)

是对的。我们不指定任何默认提取策略。我们将其保留为默认(懒惰)设置。

一旦我们开始查询,我们可以通过使用这些功能来更改延迟加载(类似于include):

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(集合)

也是如此