代码之家  ›  专栏  ›  技术社区  ›  HappyNomad

急切地加载递归关系

  •  7
  • HappyNomad  · 技术社区  · 15 年前

    我有一个递归的一对多关系,默认的惰性值为true。我可以针对NHAPI编写什么代码来有效地检索整个树,就好像我在子类别映射中有lazy=“false”一样?

    这是递归的一对多关系:

    <class name="Category" lazy="false">
        ...
        <list name="SubCategories" fetch="subselect">
                <key column="ParentCategoryID"/>
                <index column="PositionInList"/>
                <one-to-many class="Category"/>
        </list>
    

    我没有在列表中指定lazy=“false”,因为在我需要运行的大约一半查询中需要使用lazness。我已经在列表中获取了fetch=“subselect”作为我检索整个树时的优化。

    我尝试过ICriteria API:

    session.CreateCriteria<Category>().SetFetchMode( "SubCategories", FetchMode.Eager ).Add( Restrictions.IsNull("ParentCategory") ).SetResultTransformer( CriteriaSpecification.DistinctRootEntity ).List<Category>();
    

    但这只迫切地加载了层次结构中的第一层。

    3 回复  |  直到 12 年前
        1
  •  8
  •   Daniel Schilling Aaron Palmer    15 年前

    参见Ayend的网站: Efficiently Selecting a Tree . 我已经在自己的应用程序中成功地使用了这种技术。对于icriteria,它看起来是这样的:

    session.CreateCriteria<Category>()
        .SetFetchMode("SubCategories", FetchMode.Join)
        .SetResultTransformer(new DistinctRootEntityResultTransformer())
        .List<Category>()
        .Where(x => x.ParentCategory == null);
    

    此版本与您尝试的版本之间的主要区别在于如何应用“parentCategory==null”筛选器。为了检索整棵树,必须将它从发送到数据库的查询中删除-但是我们仍然需要查询只返回树的根节点,因此在数据库查询完成后,我们将使用LINQ查找这些节点。

        2
  •  1
  •   HappyNomad    12 年前

    我用丹尼尔的代码作为解决这个问题的基础。我还用我在下面共享的等效hql进行了实验。HQL执行速度稍快,但我使用了icriteria,因为我可以在fetchmodel.join和fetchmodel.lazy之间进行选择。

    session.CreateQuery( "from Category as c left join fetch c.SubCategories" )
      .SetResultTransformer( new DistinctRootEntityResultTransformer() )
      .List<Category>()
      .Where( c => c.ParentCategory == null );
    
        3
  •  0
  •   Nick Albrecht    12 年前

    不确定是否有帮助,但请看一下: map a tree in NHibernate