流利的nhibernate循环参考疼痛

时间:2013-02-08 13:13:34

标签: wcf nhibernate fluent-nhibernate

我的域A中有2个对象,而B

对象A的属性为B. 对象B具有列表

的属性

当我对我的数据库B进行命中时,它会返回一个As列表,但是每个A都有一个B,而B又有一个As列表。一遍又一遍。

显然是一个延迟加载问题。延迟加载已启用,但我的问题是这是一个WCF服务,我是否需要将我的所有域对象转换为dto对象以发送线路,当我这样做时执行以下操作 - 伪代码

ADTO adto Transform(ADomain a)
{
   adto.name = a.name;
   adto.surname = a.surname;
   adto.B = Transform(a.B);
}

BDTO bdto Transform(BDomain b)
{
   bdto.bob = b.bob;
   foreach (A a in b.As)
   {
       bdto.bs.add(Transform(a));
   }
}

所以我怎样才能使我对该集合的获取只进行一层深度。

B的映射:

HasMany(x => x.As)
            .Cascade.AllDeleteOrphan()
            .Fetch.Select()
            .Inverse().KeyColumn("AId");

A的映射:

 References(x => x.B).Column("AId");

1 个答案:

答案 0 :(得分:1)

好吧,要通过WCF传递循环引用,您应该使用IsReference参数DataContractAttribute.IsReference Property (或此处The Problem of Circular References调整父DTO(B)。

  

使用IsReference属性指示DataContractSerializer插入保留对象引用信息的XML构造。   [DataContract(Namespace = "http://domain.../", IsReference=true)]公共课BDTO ......

给你回答:

  

...所以我怎样才能使我对该集合的获取只进行一层深度。

NHibernate对循环引用没有任何问题。而且,在执行2个SQL查询时,您可以轻松获取所有数据。调整映射:

HasMany(x => x.As)
  .Cascade.AllDeleteOrphan()
  .BatchSize(25)
  //.Not.LazyLoad()
  .Inverse()
  .KeyColumn("AId");

注意:Not.LazyLoad只有在几乎总是需要A对象才能使B工作时才有意义。使用“延迟”模式时,您必须在整个WCF服务处理期间保持会话打开

BatchSize设置将优化B对象的加载列表。在此处阅读更多内容:http://ayende.com/blog/3943/nhibernate-mapping-set

NHibernate会话将执行两个查询1)Select B和2)Select A for all B并将结果具体化为完整的A和B实例,并且双向引用完全填充。 NHibernate会话将为您提供完全加载的实例。即使调用Get<A>(id)Get<B>(id)也会从会话中检索对象

接下来的步骤取决于您,您可以使用DTO对象,映射工具来转换它们......