我有一个 Reason 对象:
public class Reason
{
public virtual long Id { get; set; }
public virtual string Name { get; set; }
public virtual Company Company {get;set;}
}
我正在使用实体框架 4,公司是公司的导航属性。
我还使用网络服务将数据返回给客户端。
我有返回原因的网络方法:
[WebMethod]
public Reason[] GetCallReasons()
{
IReasonRepository rep =
ObjectFactory.GetInstance<IReasonRepository>();
return rep.GetReasonsList().ToArray();
}
由于 ef4,我在执行 Web 方法时遇到以下异常:
A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies.Reason_24A0E4BBE02EE6BC2CF30BB56CFCB670C7D9D96D03D40AF4D174B89C9D3C5537'
The problem accurs because ef4 adds property that can't be serialized:
为了解决此问题并消除错误,我可以通过不将其设为虚拟或删除导航属性来禁用导航属性。但我需要它并想使用延迟加载功能。
我还可以为 Reason 编写特定的序列化器,但我在 Web 服务中使用了很多类,为所有这些类编写序列化器需要大量工作。
我该如何解决这个异常?...
您的问题有多种解决方案,它们实际上取决于您使用的服务类型和序列化类型:
- 干净的方法是使用 DTO(数据传输对象),正如@Mikael 已经建议的那样。 DTO 是一种特殊的对象,它只传输您所需要的内容,仅此而已。您可以简单地创建不包含循环引用的 DTO 并使用自动映射器 http://automapper.codeplex.com/在实体和 DTO 之间进行映射,反之亦然。为@Mikael +1,因为他是第一个提到这一点的人。
所有其他方法都基于@Haz 建议的调整序列化:
- WCF and
DataContractSerializer
:明确标记您的实体DataContract[IsReference=true]
以及所有属性[DataMember]
属性。这将允许您使用循环引用。如果您使用 T4 模板生成实体,则必须修改它以添加这些属性。
- WCF and
DataContractSerializer
:隐式序列化。将相关导航属性之一标记为[IgnoreDataMember]
属性,以便属性不被序列化。
-
XmlSerializer
:标记相关导航属性之一[XmlIgnore]
属性
- 其他序列化:将相关导航属性之一标记为
[NonSerialized]
(Haz +1,他是第一个提到这一点的人)用于常见的序列化或[ScriptIgnore]
用于一些 JSON 相关的序列化。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)