DataContractSerializer跳过OpenAccess版本的值

时间:2009-03-21 22:41:06

标签: c# datacontractserializer openaccess

我正在使用OpenAccess断开连接的模型。当我尝试使用DataConractSerializer反序列化对象时,此对象的Version属性为0 - 但仅在xml中。如果我调试代码并观察值 - 它是1(或2,3 ......)

如果我在序列化之前说“int temp = object.Version”,则seriazlier可以保存该值。

我确定有一个懒惰的问题。如果没有显式调用,我怎么强制读取/保存这个值?

代码段:http://www.telerik.com/community/forums/orm/general-discussions/objectnetworkattacher-vs-datacontractserializer.aspx#775451

2 个答案:

答案 0 :(得分:2)

听起来[DataMember]是针对字段设置的(或默认为字段),并绕过了惰性行为。如果你控制了类型,你可以添加一个[OnSerializing]方法,在序列化开始之前偷看这个属性......这样它应该有一个值,你不需要把代码放到其他地方。

如果生成了类型,请查看它是否为partial class。如果是这样,您可以添加另一个同名的partial class(和相同的命名空间),并将[OnSerializing]方法放在那里......

示例(取消注释最后一个块以使其工作):

using System;
using System.Runtime.Serialization;
using System.Xml;

class Program {
    static void Main() {
        using (XmlWriter writer = XmlWriter.Create(Console.Out)) {
            new DataContractSerializer(typeof(Foo))
                .WriteObject(writer, new Foo());
        }       
    }
}

[DataContract]
partial class Foo {
    [DataMember(Name="Bar")]
    private int? bar;
    public int Bar {
        get {
            if (bar == null) bar = 27; // somthing lazy
            return bar.GetValueOrDefault();
        }
        set { bar = value; }
    }
}
/* UNCOMMENT THIS
partial class Foo {
    [OnSerializing]
    private void BeforeSerialize(StreamingContext ctx) {
        int tmp = Bar;
    }
}
*/

答案 1 :(得分:2)

您应该在对象上调用.Retrieve()方法,该方法将加载所有延迟加载的字段,并且您将获得序列化所需的所有数据。希望有所帮助。