问题:如何获取急切加载的条件以在根实体上返回分页结果,并将所有子集合设置为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));
}
答案 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>();