2009-09-01 120 views
4

我遇到了NHibernate尝试加载小数据层次结构的问题。我的域模型看起来像:急于在NHibernate中加载子对象和子对象集合

class GrandParent 
{ 
    int ID{get;set;} 
    IList<Parent> Parents {get; set;} 
} 

class Parent 
{ 
    IList<Child> Children {get; set;} 
} 

class Child 
{ 
} 

我想为所给的GrandParent加载所有父母和孩子。这个Linq-to-NH查询创建了正确的SQL并按预期加载了GrandParent:(该示例假定祖父母有两个父母,每个父母有两个子对象 - 总共有4个子对象)。

var linq = session.Linq<GrandParent>(); 
linq.Expand("Parents"); 
linq.Expand("Parents.Children"); 
linq.QueryOptions.RegisterCustomAction(c => 
    c.SetResultTransformer(new DistinctRootEntityResultTransformer())); 
var grandparent = (select g from session.Linq<GrandParent>() 
        where g.ID == 1 
        select g).ToList(); 

Assert(grandparent.Count == 1); //Works 
Assert(grandparent.Parents.Count == 2); //Fails - count = 4! 

grandparent.Parents集合包含4个项目,其中2个是重复的。看起来DistinctRootEntityResultTransformer只能在1级深的集合上工作,所以Parents集合会被复制,具体取决于每个父级拥有多少个Child对象。

是否有可能让NH只包含不同的父对象?

非常感谢。

+0

你能解决这个问题吗?这真的很烦人。 – 2010-03-28 10:10:29

+0

是的 - 请参阅以下有关更改IList for ICollection并在映射中使用“set”的评论。 – Simon 2010-03-31 12:15:59

回答

1

如果您的映射设置为FetchType.Join,请尝试将其更改为FetchType.Select。

+0

感谢mxmissile,然后将工作,虽然你不能在Linq-to-NH中指定获取类型(除非我失去了一些东西),并且这不是我想要一直使用的东西,所以我不愿意修改映射。 另一个解决方法是将IList <>集合更改为ICollection <>,并在映射中使用'set'而不是'bag'。我也一起骇入一个ResultTransformer来处理这个问题,并且一旦我达到了一个合理的标准,就会在这里提供一个链接。 – Simon 2009-09-09 16:44:37

+0

@Simon,你可以在映射中指定默认的获取类型 – zvolkov 2009-11-05 19:35:31

相关问题