Это не вопрос как таковой, я изучал эту тему в течение последних нескольких дней и подумал, что хотел бы поделиться чем-то, что привлекло много разрозненных идей, о которых я читал, и выдвинуло моиРешение проблемы ...
Проблема в том, что в Nhibernate требуется загрузка дочерних объектов n-го уровня, и что nHibernate не будет знать глубину дерева.Я видел, как это решается с помощью прямого sql и Union All, но, к сожалению, я не смог заставить это работать, обычно потому что nhibernate не знает, что вы загружали объекты.Поэтому я рассмотрел следующий код для загрузки объекта с использованием критерия
var children = Session.CreateCriteria<MenuNode>()
.SetFetchMode("Children", FetchMode.Eager)
.Add(Expression.Eq("Id", 1))
.List<MenuNode>();
. Это приведет к загрузке дочернего элемента для идентификатора 1, здесь вы можете использовать оператор In для загрузки нескольких объектов одновременно.Поэтому мне нужно только обработать все идентификаторы узлов, которые принадлежат этой иерархии, и стремиться загрузить их с помощью оператора In.
Итак, если я создаю родительскую таблицу для иерархии, и у каждого узла есть идентификатор иерархии, я могу получить список всех идентификаторов узлов для этой иерархии, используя эту hql
var sql = "select Distinct id from Nodes where (HierarchyId = :id) ";
var ids = Session.CreateSQLQuery(sql)
.SetInt32("id", id)
.List();
иотсюда стремятся загрузить все дочерние элементы для этого дерева в одиночку, используя
var children = Session.CreateCriteria<MenuNode>()
.SetFetchMode("Children", FetchMode.Eager)
.Add(Expression.In("Id", ids))
.List<MenuNode>();
Единственная проблема с этим состоит в том, что вы не пытались загрузить уровни первого уровня узлов из родительской таблицы иерархии, что можно сделать обычным образом..
var menu = Session.CreateCriteria<Menu>()
.SetFetchMode("RootNodes", FetchMode.Eager)
.Add(Expression.Eq("Id", id))
.List<Menu>();
Вот и все, в трех инструкциях SQL вы загрузили дочерний объект на n уровней.Для дальнейшей оптимизации я использовал несколько запросов, чтобы связать два основных запроса и отправить оба оператора одновременно.Оператор для возврата идентификатора необходимо выполнить независимо для возврата идентификатора.
Более подробную информацию об использовании MultiCriteria для быстрой загрузки можно найти здесь ..
http://nhforge.org/blogs/nhibernate/archive/2008/09/06/eager-loading-aggregate-with-many-child-collections.aspx
Надеюсь, это кому-нибудь поможет