NHibernate:递归查询

NHibernate:递归查询,nhibernate,nhibernate-mapping,Nhibernate,Nhibernate Mapping,我有一个基本的树结构,它存储在一个表中。假设这是我的模型: public class TreeNode { public virtual Guid Id { get; private set; } public virtual string Name { get; private set; } public virtual IEnumerable<TreeNode> Contents { get; private set; } } 节点名称Varchar 我想要下面的

我有一个基本的树结构,它存储在一个表中。假设这是我的模型:

public class TreeNode {
  public virtual Guid Id { get; private set; } 
  public virtual string Name { get; private set; }
  public virtual IEnumerable<TreeNode> Contents { get; private set; }
}
节点名称Varchar

我想要下面的实现,其中返回值是一个TreeNode,其中包含其子级及其子级等的满负荷树

public class Tree {
  ISessionFactory _sessions;
  public TreeNode GetBy(Guid id) {
    using(var s = _sessions.OpenSession())
      return s.Linq<TreeNode>().Single(n => n.Id == id);
  }
}
公共类树{
ISessionFactory会议;
公共树节点GetBy(Guid id){
使用(var s=\u sessions.OpenSession())
返回s.Linq().Single(n=>n.Id==Id);
}
}

我该如何做这个映射呢?

我怀疑您是否能够优化它-基本SQL中没有重复出现。您可以使用服务器端过程(特定于服务器的-某些服务器,如MySQL不支持它们)对其进行优化,但由于您得到的是非递归组件,这一点仍然值得怀疑

也许最好的方法是在加载函数中遍历树并强制执行评估。比如:

public class TreeNode {
  public virtual Guid Id { get; private set; } 
  public virtual string Name { get; private set; }
  public virtual IEnumerable<TreeNode> Contents { get; private set; }
}

public class Tree {
  ISessionFactory _sessions;
  public TreeNode GetBy(Guid id) {
    using(var s = _sessions.OpenSession()) {
      return LoadSubTree(s.Linq<TreeNode>().Single(n => n.Id == id));  
    }
  }
  private LoadSubTree(TreeNode node) {
    foreach(var n in node.Contents)
      LoadSubTree(n);
  }
}
公共类树节点{
公共虚拟Guid Id{get;private set;}
公共虚拟字符串名称{get;private set;}
公共虚拟IEnumerable内容{get;private set;}
}
公共类树{
ISessionFactory会议;
公共树节点GetBy(Guid id){
使用(var s=\u sessions.OpenSession()){
返回LoadSubTree(s.Linq().Single(n=>n.Id==Id));
}
}
私有LoadSubTree(TreeNode节点){
foreach(node.Contents中的变量n)
负荷子树(n);
}
}

PS.
可能不是
ISessionFactory
的最佳位置

您能详细说明一下“在加载函数中走下树并强制求值”吗?我不知道那是什么意思。什么是与nhibernate相关的加载函数?是的,这只是示例代码。树更像是一个无状态存储库,而不是一个实体。我在NH找到了这篇关于hiearchies的文章:这里有另一个例子供参考:
public class TreeNode {
  public virtual Guid Id { get; private set; } 
  public virtual string Name { get; private set; }
  public virtual IEnumerable<TreeNode> Contents { get; private set; }
}

public class Tree {
  ISessionFactory _sessions;
  public TreeNode GetBy(Guid id) {
    using(var s = _sessions.OpenSession()) {
      return LoadSubTree(s.Linq<TreeNode>().Single(n => n.Id == id));  
    }
  }
  private LoadSubTree(TreeNode node) {
    foreach(var n in node.Contents)
      LoadSubTree(n);
  }
}