2009-10-13 90 views
2

这个问题在网络上流传多年,我还没有找到好的解决方案。 主题是通过具有循环引用在其内部通过的NHibernate填充对象列表(具有或没有迟缓装载 - 一些网站最高审计机关它不能与懒惰来完成)循环参考,NHibernate和WCF

这里是例如:

[DataContract] 
class Person 
{ 
    [DataMemeber] 
    string Name 
    [DateMember] 
    IList<Child> myChilds; 
} 

[DataContract] 
class Child 
{ 
    [DataMemeber] 
    string Name 
    [DateMember] 
    Person Father 
} 

当我试图让所有的人在我的DB: 服务器代码将是:

ICriteria crit = session.CreateCriteria(typeof(Person))); 
IList<Base> queryResult = crit.List<Base>(); 

我获取服务器的好成绩副作用所有的人的名单,而每个人内我得到一个所有儿子的名单(并在每个儿子里面 - 我得到一个人的对象,里面有一个他的儿子列表等....)

现在,试图通过WCF获取此列表错误的通道。 (如果我从孩子中删除Person对象 - 它工作正常)。

解决方案我试过并没有解决这个问题: IsReference = true加入[DataContract] - 没有帮助。 将所有映射移动到not.Lazyload() - 没有帮助。

任何想法如何解决这个问题,而不重写WCF?

感谢, 达尼

回答

2
+0

链接现在被打破。 – Restuta 2011-02-02 12:53:28

+0

链接仍然消失 - 404。 – ssmith 2011-04-08 16:09:17

0

它看起来像你的问题是响应的大小。 WCF具有要发送的消息大小的配置。当你包含子对象时,你将超出限制。

+0

WCF的默认大小为512K。 我只有5个“Person”对象,其中只有1个有一个儿子。 这可能是一个尺寸问题 - 由于无限循环的序列化,但最初的结构,只不过是几个K的.... – Dani 2009-10-13 16:02:44

0

IsReference确实是这里的官方答案,如果你想实际保留对象图的形状。见http://msdn.microsoft.com/en-us/library/cc656708.aspx当你说“它没有帮助”时,你能详细说明你的意思吗?你究竟把IsReference放在哪里?在客户端和服务器端?你观察到了什么错误?

如果你不关心ref保存,有各种解决方案涉及打破无限参考周期。最简单的方法是从“父亲”中删除DataMember属性。或者一些与“影子属性”:

public Person Father; 
[DataMember] public string FatherName 
{ get {return Father.Name;} set {/* ... */ }} 

这实际上在很大程度上取决于您的具体要求...

+0

我已经把DataRetract属性上的IsReference, 在链接的文章中,他们说它应该在有问题的[DataMember]上,但是......令人惊讶的是 - [DataMember]不知道这个标志。这段代码不会编译! (这是非常奇怪的例子来源是MSDN ...) Systme.RunTime.Serialization DataMemberAttribute不包含IsReference = true的定义.....一个谜题。 – Dani 2009-10-14 08:19:55

+0

嗯,是的,没有注意到这个话题被打破了... 仍然: - 你把儿童和人类的IsReference类型? - 当您尝试IsReference时发生了什么? (例外等?) – 2009-10-14 16:02:49

+0

同样例外 - 没有任何变化。 例外是一般的,没有特定的。 我读过一篇文章,建议转移到另一个序列化程序。我正在检查这个选项,我会在这里报告。我已经向某人@微软询问了这篇文章,但仍在等待答案。 – Dani 2009-10-14 19:17:33