Phi*_*ker 6 nhibernate nhibernate.search
这不是一个问题,我过去几天一直在研究这个问题,并且认为我想贡献一些东西,这些东西吸引了我一直在阅读的许多不同的想法,并提出了我的解决方案.问题...
问题是在Nhibernate中急切加载n级子对象并且nHibernate不知道树的深度.我已经看到通过使用直接sql和Union All解决了这个问题,但不幸的是我无法让它工作,通常是因为nhibernate不知道你渴望加载对象.所以我查看了以下代码,以便使用条件急切加载对象
var children = Session.CreateCriteria<MenuNode>()
.SetFetchMode("Children", FetchMode.Eager)
.Add(Expression.Eq("Id", 1))
.List<MenuNode>();
Run Code Online (Sandbox Code Playgroud)
这将为Id 1加载孩子,从这里你可以使用In语句一次加载多个实体.所以我只需要计算出属于这个层次结构的所有节点id,并使用In语句急切加载它.
因此,如果我为层次结构创建一个父表,并且每个节点都有一个层次结构ID,那么我可以使用此hql获取此层次结构的所有节点标识的列表
var sql = "select Distinct id from Nodes where (HierarchyId = :id) ";
var ids = Session.CreateSQLQuery(sql)
.SetInt32("id", id)
.List();
Run Code Online (Sandbox Code Playgroud)
并从这里急切地加载所有孩子为这棵树单独使用
var children = Session.CreateCriteria<MenuNode>()
.SetFetchMode("Children", FetchMode.Eager)
.Add(Expression.In("Id", ids))
.List<MenuNode>();
Run Code Online (Sandbox Code Playgroud)
唯一的问题是你没有急切地从层次结构父表中加载第一级节点,这可以正常完成.
var menu = Session.CreateCriteria<Menu>()
.SetFetchMode("RootNodes", FetchMode.Eager)
.Add(Expression.Eq("Id", id))
.List<Menu>();
Run Code Online (Sandbox Code Playgroud)
就这样,在三个SQL语句中,您已经将一个子对象急切地加载到n个级别.为了进一步优化,我使用多查询将两个主要查询链接在一起并同时发送两个语句.为了回退id而需要独立执行以撤回id的声明.
有关使用MultiCriteria进行预加载的更多详细信息,请点击此处.
希望这对某人有所帮助
我知道你不是在问问题,但我想我应该分享我更喜欢的方式。请参阅http://ayende.com/Blog/archive/2009/08/28/nhibernate-tips-amp-tricks-efficiently-selecting-a-tree.aspx
return session.CreateCriteria<MenuNode>()
.SetFetchMode("Children", FetchMode.Join)
.SetResultTransformer(new DistinctRootEntityResultTransformer())
.List<MenuNode>();
Run Code Online (Sandbox Code Playgroud)
我不知道这是否能实现您想要通过您的方法实现的所有目标,但我发现它在处理分层数据时是一个非常有用的工具。
| 归档时间: |
|
| 查看次数: |
2046 次 |
| 最近记录: |