我有一个多对多的关系,我试图获取渴望:
*.CreateCriteria(typeof(Class1))
.SetFetchMode("Class2", FetchMode.Eager)
.SetResultTransformer(new DistinctRootEntityResultTransformer())
.SetFirstResult(20)
.SetMaxResult(10)
.List<Class1>();
我想让20-30行返回,但我有12-18。为什么?因为SetResultTransformer是在SetMaxResult之后执行的。它从第20行开始返回10行,但后来它被区分(是一个单词?),从而产生第12-18行。 我完全理解发生了什么,但想不出使用标准的解决方案......
有人有解决方法吗?
答案 0 :(得分:1)
这是因为SetMaxResults方法在“低级别”工作。
我的意思是,SetMaxResults导致NHibernate生成的SQL语句包含TOP
或LIMIT
子句。
当然,当你使用渴望的提取模式时,这会导致那些奇怪的结果,因为急切的fetchmode导致了JOIN。
因此,如果您有两个以一对多关系连接在一起的表,那么NHibernate返回的记录集就像这样
1 recordA-fromTable1 1 recordX-fromTable2
2 recordA-fromTable1 2 recordY-fromTable2
3 recordB-fromTable1 3 record2-fromTable2
如果对上述记录集执行'TOP 2',NHibernate将只能从中提取一个实体,因为结果集中的前2个记录实际上是同一个实体。
我通过使用包含TOP子句的分离子查询解决了这个问题,并检索了必须检索的实体的ID。
答案 1 :(得分:0)
我实际上没有试过这个,但它可能会奏效。
*.CreateCriteria(typeof(Class1))
.SetFirstResult(20)
.SetMaxResult(10)
.CreateCriteria("Class2", JoinType.LeftOuterJoin)
.SetResultTransformer(new DistinctRootEntityResultTransformer())
.List<Class1>();
编辑:这不起作用。 使用multiquery,multicriteria(或使用新的NH构建时的Future)
答案 2 :(得分:0)
我有同样的问题。使用分离标准和子查询对以下内容进行修改看起来可能很有希望。当我有时间的时候,我会对它进行更彻底的试验。
答案 3 :(得分:0)
public List<Employee> getData(int to, int from,
String searchField, String searchString, String searchOper,
String sord, String sidx) {
Criteria hCriteria = null;
List<Employee> viewDataList = null;
List<Employee> exactDataList = null;
try {
hSession = HibernateSessionFactory.getSession();
hTransaction = hSession.beginTransaction();
hCriteria = hSession.createCriteria(Employee.class);
if (searchString != null && searchField != null
&& searchOper != null) {
if (searchOper.equalsIgnoreCase("eq"))
hCriteria.add(Restrictions
.eq(searchField, searchString));
if (searchOper.equalsIgnoreCase("ne"))
hCriteria.add(Restrictions.ne(searchField, searchString));
if (searchOper.equalsIgnoreCase("lt"))
hCriteria.add(Restrictions.lt(searchField, searchString));
if (searchOper.equalsIgnoreCase("le"))
hCriteria.add(Restrictions.le(searchField, searchString));
if (searchOper.equalsIgnoreCase("gt"))
hCriteria.add(Restrictions.gt(searchField, searchString));
if (searchOper.equalsIgnoreCase("ge"))
hCriteria.add(Restrictions.ge(searchField, searchString));
if (searchOper.equalsIgnoreCase("cn"))
hCriteria.add(Restrictions.ilike(searchField, searchString,
MatchMode.ANYWHERE));
}
if (sord != null && sidx != null && !sidx.equals("")) {
if (sord.equals("asc"))
hCriteria.addOrder(Order.asc(sidx));
else
hCriteria.addOrder(Order.desc(sidx));
}
/*
hCriteria.setFirstResult(to);
hCriteria.setFirstResult(from);
*/
hCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
viewDataList = hCriteria.list();
// for limit
exactDataList=viewDataList.subList(from,to);
hTransaction.commit();
} catch (Exception e) {
hTransaction.rollback();
} finally {
try {
hSession.flush();
HibernateSessionFactory.closeSession();
} catch (Exception hExp) {
}
}
return exactDataList;
}