Активная загрузка дерева / иерархии с использованием Nhibernate

Это не вопрос как таковой, я исследовал эту тему последние несколько дней и подумал, что хотел бы внести свой вклад то, что втянуло множество разрозненных идей, о которых я читал, и предложило свое решение проблемы ...

Проблема заключается в том, что в Nhibernate загружаются дочерние объекты уровня n и что nHibernate не знает глубины дерева. Я видел, как это было решено с помощью прямого sql и Union All, но, к сожалению, я не мог заставить это работать, обычно потому, что nhibernate не знает, что вы нетерпеливо загружали объекты. Итак, я посмотрел на следующий код для активной загрузки объекта с использованием критерия

        var children = Session.CreateCriteria()
            .SetFetchMode("Children", FetchMode.Eager)
            .Add(Expression.Eq("Id", 1))
            .List();

. Это будет стремиться загрузить дочерний элемент для Id 1, отсюда вы можете использовать оператор In для загрузки нескольких объектов одновременно. Поэтому мне нужно только определить все идентификаторы узлов, которые принадлежат этой иерархии, и загрузить их с помощью оператора In.

Итак, если я создам родительскую таблицу для иерархии, и каждый узел будет иметь идентификатор иерархии, я могу получить список всех идентификаторов узлов » s для этой иерархии, используя этот hql

var sql = "select Distinct id from Nodes where (HierarchyId = :id) ";
var ids = Session.CreateSQLQuery(sql)
          .SetInt32("id", id)
          .List();

, и отсюда нетерпеливо загружать все дочерние элементы только для этого дерева, используя

var children = Session.CreateCriteria()
            .SetFetchMode("Children", FetchMode.Eager)
            .Add(Expression.In("Id", ids))
            .List();

. Единственная проблема с этим состоит в том, что вы не загружали уровни узлов первого уровня из родительской таблицы иерархии, что можно сделать обычным способом ..

var menu = Session.CreateCriteria()
            .SetFetchMode("RootNodes", FetchMode.Eager)
            .Add(Expression.Eq("Id", id))
            .List();

Итак, в трех операторах SQL вы с нетерпением загрузили дочерний объект на n уровней. Чтобы оптимизировать еще больше, я использовал множественный запрос, чтобы связать два основных запроса вместе и отправить оба оператора одновременно. Заявление о том, что идентификатор необходимо выполнить независимо, чтобы вернуть идентификатор.

Дополнительные сведения об использовании MultiCriteria для активной загрузки можно найти здесь.

http://nhforge.org/blogs/nhibernate/ архив / 2008/09/06 / нетерпеливая загрузка-агрегат-со-многими-дочерними-коллекциями. aspx

Надеюсь, что это поможет кому-то

6
задан marc_s 12 February 2016 в 19:58
поделиться