使用Entity Framework时,序列化出错

         在使用Entity Framework时,如果数据库中有两个表是一对多或者是多对多的关系,那么生成的实体类中就有一个导航属性。这个导航属性前面都加上了一个virtual关键字。这个virtual关键字代表这个属性的值在运行时,是延迟加载的。我们可以在Context里面关闭掉这个延迟加载的特性。

         如果一个实体类有这个导航属性,并且有virtual关键字。不管你是不是启用了延迟加载,在进行序列化的时候,都会为这个延迟属性所在的类生成一个代理类,这个代理类是真正实体类的子类。这个代理类里面有对这个类本身的自引用,所以在序列化的时候,就会陷入死循环。在前台转换成Json的数据的时候,是需要序列化的,在这个时候,就会报错,显示序列化不了。

         这时候有两种解决的办法,一种是在有这个导航属性的类上面加上一个特性。

[DataContract(IsReference = true)] 

          另外一种办法就是在实体化DataContractSerializer对象时,调用它的另外一个构造函数:

DataContractSerializer serializer = new DataContractSerializer(typeof(T), typeof(T).Name, string.Empty, null, int.MaxValue, false, true, null, null);

          不过这种方法好像只能解决序列化成xml,序列化成json的还会有问题。DataContractJsonSerializer没有类似选项。

          最后,我实际在项目中用的方法是定义DTO对象。因为我们之所以要序列化这个导航属性,是前台要用。但是前台用并不是用到这个导航属性(一般是一个对象list)的所有字段,可能只用到里面的部分字段。这时候,我们最好能定义DTO(数据传输对象),DTO对象就是定义前台界面需要用到的所有字段,前台界面只跟DTO打交道,在后台通过方法把真正的实体对象拼接成DTO对象。这样就不需要对包含导航属性的实体类进行序列化了,而是对DTO对象序列化。DTO里面不包含导航属性,就不会出现这个序列化的问题。

          参考:

          http://bbs.csdn.net/topics/390180865

          http://www.360doc.com/content/12/0612/16/466494_217702770.shtml

原文地址:https://www.cnblogs.com/xiaoxiangfeizi/p/3539856.html