所以我有一个图形对象,如下所示:
public class Graph
{
....
public virtual Node RootNode {get;set;}
}
public class Node
{
....
public virtual IList<Link> Links { get; set; }
}
public class Link
{
....
public virtual Node SourceNode { get; set; }
public virtual Node TargetNode { get; set; }
}
我使用Fluent Nhibernate映射实体。它很直接:
Graph
:References(x => x.RootNode, "root_node").Not.LazyLoad()
Node
:HasMany(x => x.Nodes).Table("nodes") .KeyColumn("graph_id").Not.LazyLoad().Inverse()
在Link
:References(x => x.TargetNode, "target_node_id ").Not.LazyLoad()
和References(x => x.SourceNode, "source_node_id")
*注意:我希望负载不是懒惰的,因为我总是向客户端发送整个对象。
使用Nhiberante Profiler我检查了写session.Get<Graph>(id)
时会发生什么。
问题是它从DB(mysql)逐个选择对象。 (选择图形,然后选择根节点,然后选择链接,然后选择目标,依此类推......)
我想要什么 用于Nhibernate选择图形,所有节点,所有链接(仅3个查询)。
我尝试了什么
是在public virtual IList<Node> Nodes { get; set; }
而不是Graph
添加RootNode
,在Node
添加public virtual bool IsRoot { get; set; }
似乎有效,但我不喜欢IsRoot
属性,因为我希望图表知道哪个节点是根。它也可能导致错误(2个节点,IsRoot = true)。
你对这个问题有什么更好的解决方案吗? 感谢。
答案 0 :(得分:0)
一种选择是将图表Id存储在节点中,并加载图表的所有节点。一旦加载完毕,它将使用缓存来获取子节点,而不是执行SQL语句。
public class Graph
{
....
public virtual Node RootNode {get;set;}
}
public class Node
{
....
public virtual Graph Graph {get;set;}
public virtual IList<Link> Links { get; set; }
}
public class Link
{
....
public virtual Node SourceNode { get; set; }
public virtual Node TargetNode { get; set; }
}