3

问题:

当我们需要序列化它们时,在处理动态代理时是否可以拉出底层 POCO?

理由:

我需要使用 EF Code First 序列化(XML)我的 POCO 实体,但很快发现它DbContext为我的 POCO 创建了动态代理,这使得序列化变得困难。

我尝试了以下方法:

  1. 在 中禁用代理创建,DbContext并且仅适用于纯 POCO。这允许我以任何我喜欢的方式序列化实例。唯一的问题是导航属性没有被跟踪,因此,当我想保存时,我必须手动附加所有相关实体,否则总是会创建新实体(参见代码示例)。
  2. 在 POCO 上实现ISerializable接口以手动处理序列化。这是很多工作,不是一个可持续的解决方案。

代码示例。

// Attach and update tags
foreach (var tag in entity.Tags)
{
    Context.Entry(tag).State = Context.Tags.Any(t => t.ID == tag.ID)
                                    ? EntityState.Modified
                                    : EntityState.Added;
}

// Attach and update state.
Context.Entry(entity).State = Context.Resources.Any(x => x.ID == entity.ID)
                                    ? EntityState.Modified
                                    : EntityState.Added;

您可以想象,当我的实体拥有更多关系时,复杂性可能会失控。

4

1 回答 1

4

当我们需要序列化它们时,在处理动态代理时是否可以拉出底层 POCO?

不,因为没有底层 POCO - 代理不是实体实例的包装器。它直接是实体实例。

您可以使用DataContractSerializerandProxyDataContractResolver序列化代理 POCO,但序列化代理实体听起来就像您正在尝试序列化启用延迟加载的实体 - 这可以序列化比您预期的要多得多,因为每个属性都将递归地延迟加载,直到没有单个未加载导航整个对象图中的属性。

在使用时,您还必须处理循环引用,方法DataContractSerializer是用 标记您的实体[DataContract(IsReference = true)]和每个可序列化的属性[DataMember]

唯一的问题是没有跟踪导航属性

没有代理的实体也会被跟踪。跟踪取决于被附加的实体而不是被代理的实体。

当我想保存时,我必须手动附加所有相关实体

如果要持久化它们,则必须始终附加反序列化实体。

于 2012-09-12T07:58:10.780 回答