【问题标题】:Serialize an Entity Framework Entity that has child Collections序列化具有子集合的实体框架实体
【发布时间】:2013-12-06 14:24:52
【问题描述】:

我有一个 Windows 应用商店应用程序。当系统暂停和关闭时,我正在尝试保存状态。我正在序列化由 Entity Framework 6 生成的 Estimate 对象。它具有存储在 Estimate Entity 的 DataServiceCollections 中的子实体。当我反序列化它时,我收到以下错误:

无法将项目添加到集合中。当 DataServiceCollection 中的项目由 DataServiceContext 跟踪时,在项目加载到集合之前无法添加新项目。

我使用的序列化函数是:

        public static string SerializeObject(object obj)
    {
        MemoryStream stream = new MemoryStream();
        System.Runtime.Serialization.Json.DataContractJsonSerializer ser = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType(), Common.SuspensionManager.KnownTypes);
        ser.WriteObject(stream, obj);
        byte[] data = new byte[stream.Length];
        stream.Seek(0, SeekOrigin.Begin);
        stream.Read(data, 0, data.Length);
        return Convert.ToBase64String(data);
    }

    public static T DeserializeObject<T>(string input)
    {
        System.Runtime.Serialization.Json.DataContractJsonSerializer ser = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
        MemoryStream stream = new MemoryStream(Convert.FromBase64String(input));
        return (T)ser.ReadObject(stream);
    }

对这些函数的调用如下:

在保存状态下序列化:

 e.PageState["SelectedEstimate"] = StringSerializer.SerializeObject(Est);

在恢复状态下反序列化:

Est = StringSerializer.DeserializeObject<Estimate>((string)e.PageState["SelectedEstimate"]);

是否有更好的序列化方法可以与 EF 实体一起使用?任何帮助将不胜感激。

吉姆

【问题讨论】:

    标签: c# entity-framework serialization windows-store-apps


    【解决方案1】:

    这是不久前发布的,但我认为它值得并回答。答案是不使用实体框架,而只是创建自己的实体。我为我的实体的子成员使用了 ObservableCollections。 EF 为您做的一件事是跟踪状态。您可以通过在 WCF 接口定义中添加枚举来自己执行此操作:

    [DataContract(Name = "RecordState")]
    public enum CustomerRecordStateEnum
    {
        [EnumMember]
        Unchanged = 0,
        [EnumMember]
        Added = 1,
        [EnumMember]
        Modified = 2,
        [EnumMember]
        Deleted = 3
    }
    

    然后在 Customer 或任何对象中都有 RecordState 的属性。

        [DataMember]
        public Nullable<CustomerRecordStateEnum> RecordState { get; set; }
    

    在生成对象的 WCF 中,将其初始化为未更改。在您的客户端中,生成的对象将实现 IPropertyChanged。您可以挂钩并将状态设置为已修改。如果没有对它做任何其他事情,你只想这样做。如果它已被添加或删除,并且您将状态更改为已修改,事情就会变得一团糟:

        void Cust_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName != "RecordState")
            {
                if (Cust.RecordState == RecordState.Unchanged)
                    Cust.RecordState = RecordState.Modified;
            }
        }
    

    创建类后客户使用:

            Cust.PropertyChanged += Cust_PropertyChanged;
    

    唯一要记住的是,如果从您的应用程序更新对象(在本例中为 Cust),请务必将 RecordState 设置回 RecordState.Unchanged。

    重点在于,使用此场景,您可以创建跟踪其记录状态的实体,并在您需要保存状态以用于暂停或其他情况时对它们进行序列化。他们会反序列化就好了。这样,在简历中,您不会从服务中加载它们。从服务加载它们会覆盖您在本地所做但尚未保存的任何更改。

    希望这对某人有用。

    吉姆

    【讨论】:

      猜你喜欢
      • 2014-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      • 2016-02-24
      相关资源
      最近更新 更多