ef4引起Web服务中的循环引用 [英] ef4 cause Circular reference in web service

查看:112
本文介绍了ef4引起Web服务中的循环引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个原因对象:

public class Reason
{
    public virtual long Id { get; set; }
    public virtual string Name { get; set; }
    public virtual Company Company {get;set;}
}

我使用实体框架4,公司是向公司的导航属性。

我还使用webservices将数据返回给客户端。

我有web方法返回原因: p>

I am using entity framework 4 and Company is navigation property to Company.
I also use webservices in order to return data to the client.
I have web method that returns Reasons:

  [WebMethod]
    public Reason[] GetCallReasons()
    {
        IReasonRepository rep =
            ObjectFactory.GetInstance<IReasonRepository>();
        return rep.GetReasonsList().ToArray();
    }

由于ef4,我得到以下执行Web方法的异常: / p>

Because of the ef4 I get the following exception for executing the web method:

A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies.Reason_24A0E4BBE02EE6BC2CF30BB56CFCB670C7D9D96D03D40AF4D174B89C9D3C5537'

问题是因为ef4添加了无法序列化的属性:

The problem accurs because ef4 adds property that can't be serialized:

按顺序为了解决这个问题并消除错误,我可以通过不使其成为虚拟或通过删除导航属性来禁用导航属性。但是我喜欢它,并希望使用懒惰的加载功能。

In order to solve this and eliminate the error, I can disable the navigation property by not making it virtual or by remove the navigation property. But I neet it and want to use the lazy loading feature.

我也可以为原因编写spesific序列化,但是我在Web服务中使用了很多类并为其编写一个序列化程序是很多工作。

I also can write spesific serializer for Reason but I have many many classes the I used in my web-services and write a serializer for all of them is a lot of work.

我如何解决这个异常?

推荐答案

对于您的问题,有多种解决方案,它们的确取决于您使用的服务类型和序列化类型:

There are multiple solutions for your problem and they really depend on the type of service you are using and on the type of serialization:


  • 干净的方法是使用DTM(数据传输对象)作为@Mikael已经建议的。 DTO是专门传输你所需要的东西,没有什么更多的东西。您可以简单地创建DTO以不包含循环引用,并使用 AutoMapper 在实体和DTO之间映射,反之亦然。为@Mikael +1,因为他是第一个提到这个。

  • The clean approach is using DTO (data transfer objects) as @Mikael already suggested. DTO is special object which transfers exactly what you need and nothing more. You can simply create DTOs to not contain circular references and use AutoMapper to map between entities and DTOs and vice versa. +1 for @Mikael because he was the first to mentioned this.

所有其他方法都是基于tweeking序列化,因为@Haz建议:

All other approaches are based on tweeking serialization as @Haz suggested:


  • WCF和 DataContractSerializer :用 DataContract [IsReference = true] 以及 [DataMember] 属性的所有属性。这将允许您使用循环引用。如果您使用T4模板生成实体,则必须修改它以为您添加这些属性。

  • WCF和 DataContractSerializer :隐式序列化。使用 [IgnoreDataMember] 属性标记相关导航属性之一,以使属性不被序列化。

  • XmlSerializer :使用标记一个相关的导航属性[XmlIgnore] 属性

  • 其他序列号:标记相关导航属性与 [NonSerialized] (+1为哈姆他是第一个提到这个)为普通序列化或 [ScriptIgnore] 对于某些JSON相关序列化。

  • WCF and DataContractSerializer: explicitly mark your entities with DataContract[IsReference=true] and all properties with [DataMember] attributes. This will allow you to use circular references. If you are using T4 template to generate entities you must modify it to add these attributes for you.
  • WCF and DataContractSerializer: implicit serialization. Mark one of related navigation properties with [IgnoreDataMember] attribute so that property is not serialized.
  • XmlSerializer: mark one fo related navigation properties with [XmlIgnore] attribute
  • Other serializations: mark one of related navigation properties with [NonSerialized] (+1 for Haz he was the first to mention this) for common serialization or [ScriptIgnore] for some JSON related serialization.

这篇关于ef4引起Web服务中的循环引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆