Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Este artigo descreve os recursos de serialização do LINQ to SQL. Os parágrafos que se seguem fornecem informações sobre como adicionar serialização durante a geração de código no momento do design e o comportamento de serialização em tempo de execução das classes LINQ para SQL.
Você pode adicionar código de serialização em tempo de design por um dos seguintes métodos:
No Object Relational Designer, altere a propriedade Serialization Mode para Unidirectional.
Na linha de comando SQLMetal, adicione a opção /serialization . Para obter mais informações, consulte SqlMetal.exe (Ferramenta de geração de código).
Visão geral
O código gerado pelo LINQ to SQL fornece recursos de carregamento diferido por padrão. O carregamento diferido é muito conveniente no nível intermediário para o carregamento transparente de dados sob demanda. No entanto, é problemático para a serialização, porque o serializador dispara o carregamento diferido, quer o carregamento diferido seja pretendido ou não. Com efeito, quando um objeto é serializado, o seu fecho transitivo sob todas as referências de saída com carregamento deferido é serializado.
O recurso de serialização LINQ to SQL resolve esse problema, principalmente por meio de dois mecanismos:
Um DataContext modo para desativar o carregamento diferido (ObjectTrackingEnabled). Para obter mais informações, consulte DataContext.
Um interruptor de geração de código para gerar atributos System.Runtime.Serialization.DataContractAttribute e System.Runtime.Serialization.DataMemberAttribute em entidades geradas. Este aspeto, incluindo o comportamento de classes com adiamento de carregamento durante a serialização, é o assunto principal deste tópico.
Definições
Serializador DataContract: serializador padrão usado pelo componente WCF (Windows Communication Framework) do .NET Framework 3.0 ou versões posteriores.
Serialização unidirecional: A versão serializada de uma classe que contém apenas uma propriedade de associação unidirecional (para evitar um ciclo). Por convenção, a propriedade no lado principal de uma relação de chave primária e estrangeira é indicada para serialização. O outro lado em uma associação bidirecional não é serializado.
A serialização unidirecional é o único tipo de serialização suportado pelo LINQ to SQL.
Exemplo de código
O seguinte código utiliza as classes tradicionais Customer e Order do banco de dados de exemplo Northwind e mostra como estas classes são decoradas com atributos de serialização.
// The class is decorated with the DataContract attribute.
[Table(Name="dbo.Customers")]
[DataContract()]
public partial class Customer : INotifyPropertyChanging, INotifyPropertyChanged
{
' The class is decorated with the DataContract attribute.
<Table(Name:="dbo.Customers"), _
DataContract()> _
Partial Public Class Customer
Implements System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged
// Private fields are not decorated with any attributes, and are
// elided.
private string _CustomerID;
// Public properties are decorated with the DataMember
// attribute and the Order property specifying the serial
// number. See the Order class later in this topic for
// exceptions.
public Customer()
{
this.Initialize();
}
[Column(Storage="_CustomerID", DbType="NChar(5) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
[DataMember(Order=1)]
public string CustomerID
{
get
{
return this._CustomerID;
}
set
{
if ((this._CustomerID != value))
{
this.OnCustomerIDChanging(value);
this.SendPropertyChanging();
this._CustomerID = value;
this.SendPropertyChanged("CustomerID");
this.OnCustomerIDChanged();
}
}
}
' Private fields are not decorated with any attributes,
' and are elided.
Private _CustomerID As String
' Public properties are decorated with the DataMember
' attribute and the Order property specifying the
' serial number. See the Order class later in this topic
' for exceptions
<Column(Storage:="_CustomerID", DbType:="NChar(5) NOT NULL", CanBeNull:=false, IsPrimaryKey:=true), _
DataMember(Order:=1)> _
Public Property CustomerID() As String
Get
Return Me._CustomerID
End Get
Set
If ((Me._CustomerID = value) _
= false) Then
Me.OnCustomerIDChanging(value)
Me.SendPropertyChanging
Me._CustomerID = value
Me.SendPropertyChanged("CustomerID")
Me.OnCustomerIDChanged
End If
End Set
End Property
// The following Association property is decorated with
// DataMember because it is the parent side of the
// relationship. The reverse property in the Order class
// does not have a DataMember attribute. This factor
// prevents a 'cycle.'
[Association(Name="FK_Orders_Customers", Storage="_Orders", OtherKey="CustomerID", DeleteRule="NO ACTION")]
[DataMember(Order=13)]
public EntitySet<Order> Orders
{
get
{
return this._Orders;
}
set
{
this._Orders.Assign(value);
}
}
' The following Association property is decorated with
' DataMember because it is the parent side of the
' relationship. The reverse property in the Order
' class does not have a DataMember attribute. This
' factor prevents a 'cycle.'
<Association(Name:="FK_Orders_Customers", Storage:="_Orders", OtherKey:="CustomerID", DeleteRule:="NO ACTION"), _
DataMember(Order:=13)> _
Public Property Orders() As EntitySet(Of [Order])
Get
Return Me._Orders
End Get
Set(ByVal value As EntitySet(Of [Order]))
Me._Orders.Assign(Value)
End Set
End Property
Para a Order classe no exemplo a seguir, somente a propriedade de associação reversa correspondente à Customer classe é mostrada por questões de brevidade. Não tem um DataMemberAttribute atributo para evitar um ciclo.
// The class for the Orders table is also decorated with the
// DataContract attribute.
[Table(Name="dbo.Orders")]
[DataContract()]
public partial class Order : INotifyPropertyChanging, INotifyPropertyChanged
' The class for the Orders table is also decorated with the
' DataContract attribute.
<Table(Name:="dbo.Orders"), _
DataContract()> _
Partial Public Class [Order]
Implements System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged
// Private fields for the Orders table are not decorated with
// any attributes, and are elided.
private int _OrderID;
// Public properties are decorated with the DataMember
// attribute.
// The reverse Association property on the side of the
// foreign key does not have the DataMember attribute.
[Association(Name = "FK_Orders_Customers", Storage = "_Customer", ThisKey = "CustomerID", IsForeignKey = true)]
public Customer Customer
' Private fields for the Orders table are not decorated with
' any attributes, and are elided.
Private _CustomerID As String
' Public properties are decorated with the DataMember
' attribute.
' The reverse Association property on the side of the
' foreign key does not have the DataMember attribute.
<Association(Name:="FK_Orders_Customers", Storage:="_Customer", ThisKey:="CustomerID", IsForeignKey:=true)> _
Public Property Customer() As Customer
Como serializar as entidades
Você pode serializar as entidades nos códigos mostrados na seção anterior da seguinte maneira;
Northwnd db = new Northwnd(@"c\northwnd.mdf");
Customer cust = db.Customers.Where(c => c.CustomerID ==
"ALFKI").Single();
DataContractSerializer dcs =
new DataContractSerializer(typeof(Customer));
StringBuilder sb = new StringBuilder();
XmlWriter writer = XmlWriter.Create(sb);
dcs.WriteObject(writer, cust);
writer.Close();
string xml = sb.ToString();
Dim db As New Northwnd("...")
Dim cust = (From c In db.Customers _
Where c.CustomerID = "ALFKI").Single
Dim dcs As New DataContractSerializer(GetType(Customer))
Dim sb As StringBuilder = New StringBuilder()
Dim writer As XmlWriter = XmlWriter.Create(sb)
dcs.WriteObject(writer, cust)
writer.Close()
Dim xml As String = sb.ToString()
Self-Recursive Relacionamentos
As relações auto-recursivas seguem o mesmo padrão. A propriedade de associação correspondente à chave estrangeira não possui o atributo DataMemberAttribute, enquanto a propriedade pai possui.
Considere a seguinte classe que tem duas relações autorrecursivas: Empregado.Gerente/Relatórios e Empregado.Mentor/Mentees.
// No DataMember attribute.
public Employee Manager;
[DataMember(Order = 3)]
public EntitySet<Employee> Reports;
// No DataMember
public Employee Mentor;
[DataMember(Order = 5)]
public EntitySet<Employee> Mentees;
' No DataMember attribute
Public Manager As Employee
<DataMember(Order:=3)> _
Public Reports As EntitySet(Of Employee)
' No DataMember attribute
Public Mentor As Employee
<DataMember(Order:=5)> _
Public Mentees As EntitySet(Of Employee)