单个实体参考的WCF序列化和NHibernate代理

时间:2011-11-17 10:17:30

标签: wcf nhibernate

假设NHibernate实体“School”具有“Manager”属性,该属性引用“Person”类型的单个实体。

要成为“WCF就绪”,人物将被DataContractAtrribute修饰。 School.Manager的Fluent NH映射为References(s => s.Manager)。 当WCF将类型为“School”的实体发送给客户端时,我会收到一条例外消息,其中包含以下消息:

  

“类型'Castle.Proxies.PersonProxy'不能是ISerializable并且具有DataContractAttribute属性”

现在,这仅在引用单个实体(而不是通过集合)时发生。 我的解决方法是通过将.Not.LazyLoad()添加到References子句来禁用代理。

是否有人遇到此问题或有任何想法如何解决?

谢谢, ELAD

2 个答案:

答案 0 :(得分:3)

如果您选择不加载引用的实体急切,NHibernate将创建动态代理(以便将来可以在某个时刻初始化对象)。这是标准行为。

现在,对于对象列表,NHibernate将使用其代理集合之一(例如,PersistentGenericBag)。由于集合类型是已知的,因此可以序列化。相反,当它接近你的实体类时会发生什么?它将根据您的类型生成动态代理,这将无法序列化(由于它具有运行时导向/动态特性)。

这是内置的机制,我不认为你可以做很多事情。但是,你有两个解决这个问题的方法:

  • 使用Not.LazyLoad()就像你现在正在做的那样,强制实例创建
  • 或者,您可以在通过网络服务发送之前将Manager设置为null。无论如何,你不会在客户端使用代理(因为会话将会很久)。

答案 1 :(得分:2)

扩展jimmy_keen的答案,还有其他一些选择

  • 在序列化之前加载时,将fetchmode设置为渴望参考
  • 将域对象复制到DTO- /消息对象以通过线路发送(良好的做法是控制更多,通过线路传输)
  • 实施IDataContractSurrogate请参阅here