【发布时间】:2011-04-09 02:42:03
【问题描述】:
这不是一个问题,过去几天我一直在研究这个主题,并想贡献一些东西来吸引我一直在阅读的许多不同的想法并提出我的解决问题...
问题是在 Nhibernate 中急切加载 n 级子对象,并且 nHibernate 将不知道树的深度。我已经看到通过使用直接 sql 和 Union All 解决了这个问题,但不幸的是我无法让它工作,通常是因为 nhibernate 不知道你已经急切地加载了对象。因此,我查看了以下代码以使用标准急切加载对象
var children = Session.CreateCriteria<MenuNode>()
.SetFetchMode("Children", FetchMode.Eager)
.Add(Expression.Eq("Id", 1))
.List<MenuNode>();
这将预先加载 ID 1 的子实体,从这里您可以使用 In 语句一次预先加载多个实体。所以我只需要计算出属于这个层次结构的所有节点 id 并使用 In 语句急切地加载它。
因此,如果我为层次结构创建一个父表并且每个节点都有一个层次结构 ID,那么我可以使用此 hql 获取此层次结构的所有节点 ID 的列表
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 级。为了进一步优化,我使用多查询将两个主要查询链接在一起并同时发送两个语句。拉回id的语句需要独立执行才能拉回id。
可以在此处找到使用 MultiCriteria 进行预加载的更多详细信息。
希望这对某人有所帮助
【问题讨论】:
标签: nhibernate nhibernate.search