Как видно из названия, у меня возникли некоторые проблемы с сериализацией моих автоматически сгенерированных объектов POCO.Но сначала некоторая справочная информация:
Я создал свой уровень доступа к данным, используя EF 4.0 en ADO.Net POCO Entity Generator, следуя этому руководству: http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx.
У меня сейчас 2библиотеки классов, одна с моделью EF, вторая с объектами POCO, сгенерированными автоматическими T4.
В настоящее время я работаю над другим проектом, в котором я хочу использовать свои библиотеки классов DAL.Я должен получить некоторые объекты и сериализовать их в XML.Сначала я попробовал XmlSerializer, но потом обнаружил, что у него проблемы с циркулярными ссылками.Я исправил эту проблему с помощью XmlIgnore, но затем у меня возникла проблема с сериализацией:
Public Overridable Property NwlGroup As ICollection(Of NwlGroup)
Поскольку XmlSerializer не поддерживает интерфейсы.
Во-вторых, я попробовал DataContractSerializer с атрибутами [DataContract] и [DataMember]в автоматически сгенерированном файле Poco Class.Это сработало, но, естественно, мне пришлось очистить изменения от автоматически сгенерированного файла, поэтому я хотел использовать атрибут 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()
Это дало мне NewsletterCustomerXML со всеми свойствами чтения / записи, сериализованными так, как вы ожидаете, если не указан DataContract.Если я перемещу атрибут DataContract из NewsletterCustomerMetadata в NewsletterCustomer, то я получу только корневой узел, как вы ожидаете, когда DataContract указан без атрибутов DataMember.
Похоже, DataContractSerializer не работает с аннотациями данных MetaDataType.
Мои вопросы:
- Как я могу сериализовать мои классы POCO в CUSTOM XML?
- Как добавить атрибуты [DataContract] и [DataMember] в autoсгенерированные классы POCO?
- Каков наилучший способ сериализации автоматически сгенерированных классов POCO в XML?