C# ef4导致web服务中的循环引用
我有一个理由:C# ef4导致web服务中的循环引用,c#,.net,web-services,entity-framework,serialization,C#,.net,Web Services,Entity Framework,Serialization,我有一个理由: public class Reason { public virtual long Id { get; set; } public virtual string Name { get; set; } public virtual Company Company {get;set;} } 我使用的是实体框架4,公司是公司的导航属性。 我还使用Web服务将数据返回到客户端。 我有返回原因的web方法: [WebMethod] public Rea
public class Reason
{
public virtual long Id { get; set; }
public virtual string Name { get; set; }
public virtual Company Company {get;set;}
}
我使用的是实体框架4,公司是公司的导航属性。我还使用Web服务将数据返回到客户端。
我有返回原因的web方法:
[WebMethod]
public Reason[] GetCallReasons()
{
IReasonRepository rep =
ObjectFactory.GetInstance<IReasonRepository>();
return rep.GetReasonsList().ToArray();
}
由于ef4添加了无法序列化的属性,因此出现了问题:
为了解决这个问题并消除错误,我可以通过不将导航属性设置为虚拟或删除导航属性来禁用它。但是我需要它,并且想要使用延迟加载特性
出于某种原因,我也可以编写spesific序列化程序,但我在web服务中使用了许多类,为所有这些类编写序列化程序需要大量的工作
如何解决此异常?。您尚未提供公司类的定义。。。。但我猜你有很多理由 SOA环境中的延迟加载实际上不起作用。在序列化类上不能有无限的延迟导航,一旦离开webmethod,就无法从webmethod使用者调用原始datacontext来查找属性。。。因此,序列化程序将尝试访问所有属性,包括序列化时的惰性属性 您需要对循环引用的一部分禁用序列化,可以是对Company类中的Reason集合,也可以是Reason类中的Company
您可以使用“NotSerialized”属性来禁用特定字段的序列化。我通常为Web服务编写特定的类。虽然这是一些额外的工作,但它的优点是Web服务变得更加健壮,因为实体中的小更改不会被忽略,并且不会在使用者/javascript方面悄无声息地失败。例如,如果我更改了属性的名称
您可以做一些事情来减少工作量,其中之一是使用AutoMapper,它可以在对象之间自动映射 您的问题有多种解决方案,它们实际上取决于您使用的服务类型和序列化类型:
- 干净的方法是使用DTO(数据传输对象),正如@Mikael已经建议的那样。DTO是一种特殊的对象,它可以准确地传输您所需要的内容,仅此而已。您可以简单地创建不包含循环引用的DTO,并使用它在实体和DTO之间映射,反之亦然+因为他是第一个提到这一点的人
- WCF和
:使用DataContractSerializer
显式标记实体,并使用DataContract[IsReference=true]
属性标记所有属性。这将允许您使用循环引用。如果您使用T4模板生成实体,则必须对其进行修改,以便为您添加这些属性[DataMember]
- WCF和
:隐式序列化。使用DataContractSerializer
属性标记一个相关导航属性,以便属性不会序列化[IgnoreDataMember]
:使用XmlSerializer
属性标记一个相关导航属性[XmlIgnore]
- 其他序列化:使用
标记一个相关的导航属性(Haz是第一个提到这一点的人,他是+1)用于普通序列化,或使用[NonSerialized]
标记一些与JSON相关的序列化[ScriptIgnore]
A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies.Reason_24A0E4BBE02EE6BC2CF30BB56CFCB670C7D9D96D03D40AF4D174B89C9D3C5537'