2010-08-06 111 views
0

我有一個存儲在單個表中的基本樹結構。比方說,這是我的模型:NHibernate:遞歸查詢

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; } 
} 

和表:

TREE_NODES 
    PK_NODE Guid 
    FK_NODE_PARENT Guid 

NODE_NAME的Varchar

我想下面的實現,其中返回值是充分即時加載樹一樹節點其子女及其子女等

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

我該怎麼做m apping?

回答

1

我懷疑你可以優化它 - 在基本的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); 
    } 
} 

PS。 Tree可能不是ISessionFactory的最佳地點。

+0

您能否詳細說明「在樹上裝載功能並強制評估」?我不知道這意味着什麼。什麼是與nhibernate有關的加載函數? – 2010-08-06 17:12:09

+0

是的,這只是示例代碼。樹更像是一個無狀態的存儲庫,而不是一個實體。我發現這篇關於NH的文章:http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/05/14/how-to-map-a-tree-in-nhibernate.aspx – 2010-08-06 18:22:10

+0

這裏有另一個參考例子:http://refactoringaspnet.blogspot.com/2011/04/using-common-table-expressions-to.html – 2011-05-07 10:39:55