我需要加载一个名为Node的复杂对象......它并不复杂......它看起来如下: -
节点具有对EntityType的引用,该引用与Property具有一对多关系,而Property又与PorpertyListValue具有一对多关系
public class Node
{
public virtual int Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
public virtual EntityType Etype
{
get;
set;
}
}
public class EntityType
{
public virtual int Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
public virtual IList<Property> Properties
{
get;
protected set;
}
public EntityType()
{
Properties = new List<Property>();
}
}
public class Property
{
public virtual int Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
public virtual EntityType EntityType
{
get;
set;
}
public virtual IList<PropertyListValue> ListValues
{
get;
protected set;
}
public virtual string DefaultValue
{
get;
set;
}
public Property()
{
ListValues = new List<PropertyListValue>();
}
}
public class PropertyListValue
{
public virtual int Id
{
get;
set;
}
public virtual Property Property
{
get;
set;
}
public virtual string Value
{
get;
set;
}
protected PropertyListValue()
{
}
}
我试图做的是一次加载所有子对象的 Node 对象。没有延迟加载。原因是我在数据库中有数千个节点对象,我必须使用 WCF 服务通过网络发送它们。我遇到了类 SQL N+1 问题。我正在使用带有 Automapping 的 Fluent Nhibernate,而 NHibernate Profiler 建议我使用FetchMode.Eager一次加载整个对象。我正在使用以下 qyuery
Session.CreateCriteria(typeof (Node))
.SetFetchMode( "Etype", FetchMode.Join )
.SetFetchMode( "Etype.Properties", FetchMode.Join )
.SetFetchMode( "Etype.Properties.ListValues", FetchMode.Join )
或使用 NHibernate LINQ
Session.Linq<NodeType>()
.Expand( "Etype")
.Expand( "Etype.Properties" )
.Expand( "Etype.Properties.ListValues" )
当我运行上述任何查询时,它们都会生成一个带有所有左外连接的相同查询,这正是我所需要的。但是,由于某种原因,查询返回的 IList 没有被加载到对象中。实际上返回的Nodes计数等于查询的行数,因此Nodes对象是重复的。此外,每个Node中的属性都是重复的,Listvalues也是如此。
所以我想知道如何修改上述查询以返回所有具有属性和列表值的唯一节点。