【问题标题】:NHibernate ManyToMany and eager loading: strange resultset for SetFetchmode combined with SetResultTransformer and SetMaxResultNHibernate ManyToMany 和急切加载:SetFetchmode 结合 SetResultTransformer 和 SetMaxResult 的奇怪结果集
【发布时间】:2012-10-12 02:09:56
【问题描述】:

我有一个多对多的关系,我试图急切地获取它:

*.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 行。 我完全理解发生了什么,但想不出使用标准的解决方案......

有没有人可以解决这个问题?

【问题讨论】:

标签: nhibernate many-to-many


【解决方案1】:

这是因为 SetMaxResults 方法工作在“低级别”。 我的意思是,SetMaxResults 导致 NHibernate 生成的 SQL 语句包含 TOPLIMIT 子句。

当然,当您使用急切获取模式时,这会导致那些奇怪的结果,因为急切获取模式会导致 JOIN。

因此,如果您有 2 个表以一对多的关系连接在一起,则 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。

【讨论】:

    【解决方案2】:

    我实际上并没有尝试过,但它可能会起作用。

      *.CreateCriteria(typeof(Class1))
        .SetFirstResult(20)
        .SetMaxResult(10)
        .CreateCriteria("Class2", JoinType.LeftOuterJoin)
        .SetResultTransformer(new DistinctRootEntityResultTransformer())
        .List<Class1>();
    

    编辑:这不起作用。 使用多查询、多条件(或使用新版本的 NH 时的 Future)

    【讨论】:

    • 我试过了。它不起作用。它与原始帖子存在完全相同的问题。
    • 我现在知道了,这是不可能的,因为这是一个非常低效的查询。你应该使用多查询
    • 您能否提供更多关于如何使用多条件、多查询和未来功能的详细信息(最好是针对此问题的示例)?我也有同样的问题,我不太确定如何使用提到的功能来完成这个问题的目标。
    • 内森,你可能想读这个:nhforge.org/blogs/nhibernate/archive/2008/09/06/…
    【解决方案3】:

    我也有同样的问题。使用分离的标准和子查询对以下内容进行改编看起来可能很有希望。有时间我会做一个更彻底的试验。

    http://blogs.taiga.nl/martijn/2008/11/20/nhibernate-criteria-queries-across-multiple-many-many-associations/

    【讨论】:

      【解决方案4】:
       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;
      
      }
      

      【讨论】:

        猜你喜欢
        • 2015-10-22
        • 1970-01-01
        • 2010-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多