NHibernate寻呼标准与fetchmode渴望。 (使用流利的NH)

时间:2010-12-01 21:46:17

标签: fluent-nhibernate nhibernate-mapping

问题:如何获取急切加载的条件以在根实体上返回分页结果,并将所有子集合设置为fetchmode = eager。

我正在尝试使用预先加载的子集合获取10项分页结果集。问题是查询做了一个选择前10个包裹整个选择。导致它只返回前10个结果,包括所有连接的记录。如果第一个实体有10个子对象,那么我的结果集将返回1个实体,其中加载了10个子对象。我需要实体和子集合返回水合(懒惰)。如果我关闭延迟加载并运行此查询,我会得到结果集中每个关联的n + 1查询。

这是我的基本查询过程:

criteria = context.Session.CreateCriteria<Associate>();
criteria.SetMaxResults(10); //hardcoded for testing
criteria.SetFirstResult(1); //hardcoded for testing
criteria.SetFetchMode("Roles", NHibernate.FetchMode.Eager);
criteria.SetFetchMode("Messages", NHibernate.FetchMode.Eager);
criteria.SetFetchMode("DirectReports", NHibernate.FetchMode.Eager);
criteria.SetResultTransformer(new DistinctRootEntityResultTransformer());
return criteria.List<Associate>();


public AssociateMap()
    {
        ReadOnly();
        Id(x => x.AssociateId);
        Map(x => x.FirstName);
        Map(x => x.LastName);
        Map(x => x.ManagerId);
        Map(x => x.Department);
        Map(x => x.Email);
        Map(x => x.JobTitle);

        Map(x => x.LastFirstName).Formula("LTRIM(RTRIM(LastName)) + ', ' + LTRIM(RTRIM(FirstName))");

        HasMany(x => x.Messages).KeyColumn("AssociateId").Inverse().Cascade.All();
        HasMany(x => x.Roles).Element("RoleKey");
        HasMany(x => x.DirectReports).KeyColumn("ManagerId").Cascade.None().ForeignKeyConstraintName("FK_Associate_Manager");
        //HasMany(x => x.DirectReports).Element("ManagerId").CollectionType(typeof(Domain.Associate));


    }

1 个答案:

答案 0 :(得分:3)

解决方案最终使用子查询来设置最大结果。我使用Subqueries.PropertyIn添加了子查询。我将“条件”克隆为“限制器”,因为我在未显示的代码中添加了条件表达式。所以我需要将这些标准克隆到子查询中,因此前10个选择将在“IN”语句中。现在我可以急切地加载子集合并为根实体添加分页以获得10个内容而不会出现笛卡尔或n + 1问题。我将尝试跟进更完整和有组织的代码。

//criteria = context.Session.CreateCriteria<Associate>(); 
//changed criteria to DetachedCriteria.
criteria = DetachedCriteria.For<Associate>();

DetachedCriteria limiter = CriteriaTransformer.Clone(criteria); 
limiter.SetProjection(Projections.Id());
limiter.SetMaxResults(10);
criteria.Add(Subqueries.PropertyIn("AssociateId", limiter));

criteria.SetFetchMode("Roles", NHibernate.FetchMode.Eager); 
criteria.SetFetchMode("Messages", NHibernate.FetchMode.Eager); 
criteria.SetFetchMode("DirectReports", NHibernate.FetchMode.Eager); 
criteria.SetResultTransformer(new DistinctRootEntityResultTransformer()); 
return criteria.List<Associate>();