【发布时间】:2011-06-08 08:52:10
【问题描述】:
正如标题所说,我在序列化自动生成的 POCO 对象时遇到了一些问题。但首先是一些背景信息:
我按照本指南使用 EF 4.0 en ADO.Net POCO 实体生成器创建了我的数据访问层:http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx。
我现在有 2 个类库,一个带有 EF 模型,第二个带有 T4 自动生成的 POCO 实体。
目前我正在处理另一个我想使用我的 DAL 类库的项目。我必须检索一些对象并将它们序列化为 XML。首先我尝试了 XmlSerializer,但后来我发现它在循环引用方面存在问题。我使用 XmlIgnore 解决了这个问题,但后来我遇到了序列化问题:
Public Overridable Property NwlGroup As ICollection(Of NwlGroup)
因为 XmlSerializer 不支持接口。
其次,我在自动生成的实体 Poco 类文件中尝试了具有 [DataContract] 和 [DataMember] 属性的 DataContractSerializer。这行得通,但自然我必须从自动生成的文件中清理更改,因此我想使用 MetaDataType 属性。我创建了这样的额外文件:
Imports System.Runtime.Serialization
Imports System.ComponentModel.DataAnnotations
<MetadataType(GetType(NewsletterCustomerMetadata))>
Partial Public Class NewsletterCustomer
End Class
<DataContract()
Public Class NewsletterCustomerMetadata
<DataMember(Name:="emailaddress", IsRequired:=True)>
Public Overridable Property Emailaddress As String
<DataMember(Name:="name")>
Public Overridable Property Name As String
<DataMember()>
Public Overridable Property NwlGroup As ICollection(Of NwlGroup)
End Class
自动生成文件:
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated from a template.
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.Runtime.Serialization
Public Class NewsletterCustomer
#Region "Primitive Properties"
Public Overridable Property ID As Integer
Public Overridable Property Emailaddress As String
Public Overridable Property Name As String
...
#Region "Navigation Properties"
Public Overridable Property NwlGroup As ICollection(Of NwlGroup)
Get
If _nwlGroup Is Nothing Then
Dim newCollection As New FixupCollection(Of NwlGroup)
AddHandler newCollection.CollectionChanged, AddressOf FixupNwlGroup
_nwlGroup = newCollection
End If
Return _nwlGroup
End Get
Set(ByVal value As ICollection(Of NwlGroup))
If _nwlGroup IsNot value Then
Dim previousValue As FixupCollection(Of NwlGroup) = TryCast(_nwlGroup, FixupCollection(Of NwlGroup))
If previousValue IsNot Nothing Then
RemoveHandler previousValue.CollectionChanged, AddressOf FixupNwlGroup
End If
_nwlGroup = value
Dim newValue As FixupCollection(Of NwlGroup) = TryCast(value, FixupCollection(Of NwlGroup))
If newValue IsNot Nothing Then
AddHandler newValue.CollectionChanged, AddressOf FixupNwlGroup
End If
End If
End Set
End Property
Private _nwlGroup As ICollection(Of NwlGroup)
...
End Class
然后我尝试将其序列化为 xml
Dim ctx = New ModelEntities(_connectionString)
ctx.ContextOptions.ProxyCreationEnabled = False
ctx.ContextOptions.LazyLoadingEnabled = False
Dim customers = From c In ctx.NwlCustomer
Select c
Where c.SiID = 99
Dim filename As String = "C:\test.txt"
Dim result As NewsletterCustomer = customers.ToList.FirstOrDefault
Dim writer As New FileStream(filename, FileMode.Create)
Dim ser As New DataContractSerializer(GetType(NewsletterCustomer))
ser.WriteObject(writer, customers.ToList.FirstOrDefault)
writer.Close()
这给了我 NewsletterCustomer xml,其中所有读/写属性都序列化,就像没有指定 DataContract 时所期望的那样。如果我将 DataContract 属性从 NewsletterCustomerMetadata 移动到 NewsletterCustomer,那么当 DataContract 没有指定 DataMember 属性时,我只会得到根节点。
看起来 DataContractSerializer 不适用于 MetaDataType 数据注释。
我的问题是:
- 如何将我的 POCO 类序列化为 CUSTOM XML?
- 如何将 [DataContract] 和 [DataMember] 属性添加到自动生成的 POCO 类中?
- 将自动生成的 POCO 类序列化为 XML 的最佳方法是什么?
【问题讨论】:
标签: .net entity-framework xml-serialization datacontractserializer