SerializaciónSerialization

Este tema se describe LINQ to SQLLINQ to SQL características de la serialización.This topic describes LINQ to SQLLINQ to SQL serialization capabilities. En los párrafos siguientes se proporciona información sobre cómo agregar la característica de serialización durante la generación de código en tiempo de diseño y el comportamiento de serialización en tiempo de ejecución de las clases LINQ to SQLLINQ to SQL.The paragraphs that follow provide information about how to add serialization during code generation at design time and the run-time serialization behavior of LINQ to SQLLINQ to SQL classes.

Puede agregar código de serialización en tiempo de diseño mediante cualquiera de estos métodos:You can add serialization code at design time by either of the following methods:

  • En Object Relational Designer, cambie el modo de serialización propiedad Unidirectional.In the Object Relational Designer, change the Serialization Mode property to Unidirectional.

  • En la línea de comandos SQLMetal, agregue el /serialization opción.On the SQLMetal command line, add the /serialization option. Para obtener más información, vea SqlMetal.exe (Herramienta de generación de código).For more information, see SqlMetal.exe (Code Generation Tool).

Información generalOverview

El código generado por LINQ to SQLLINQ to SQL proporciona funcionalidad de carga aplazada de forma predeterminada.The code generated by LINQ to SQLLINQ to SQL provides deferred loading capabilities by default. La carga aplazada es muy apropiada en el nivel intermedio, para una carga de datos transparente a petición.Deferred loading is very convenient on the mid-tier for transparent loading of data on demand. Sin embargo, da problemas para la serialización, porque el serializador activa la carga aplazada esté prevista o no.However, it is problematic for serialization, because the serializer triggers deferred loading whether deferred loading is intended or not. De hecho, cuando se serializa un objeto, se serializa su cierre transitivo en todas las referencias con carga aplazada salientes.In effect, when an object is serialized, its transitive closure under all outbound defer-loaded references is serialized.

El LINQ to SQLLINQ to SQL característica de serialización resuelve este problema, principalmente mediante dos mecanismos:The LINQ to SQLLINQ to SQL serialization feature addresses this problem, primarily through two mechanisms:

DefinicionesDefinitions

  • Serializador DataContract: Serializador predeterminado utilizado por el componente de Windows Communication Framework (WCF) del .NET Framework 3.0 o versiones posteriores.DataContract serializer: Default serializer used by the Windows Communication Framework (WCF) component of the .NET Framework 3.0 or later versions.

  • Serialización unidireccional: La versión serializada de una clase que contiene sólo una propiedad de asociación unidireccional (para evitar un ciclo).Unidirectional serialization: The serialized version of a class that contains only a one-way association property (to avoid a cycle). Por convención, se marca para la serialización la propiedad que se encuentra en el lado primario de una relación de clave externa y clave principal.By convention, the property on the parent side of a primary-foreign key relationship is marked for serialization. No se serializa el otro lado en una asociación bidireccional.The other side in a bidirectional association is not serialized.

    La serialización unidireccional es el único tipo de serialización que LINQ to SQLLINQ to SQL admite.Unidirectional serialization is the only type of serialization supported by LINQ to SQLLINQ to SQL.

Ejemplo de códigoCode Example

El código siguiente utiliza las clases Customer y Order tradicionales de la base de datos de ejemplo Northwind y muestra cómo estas clases se decoran con atributos de serialización.The following code uses the traditional Customer and Order classes from the Northwind sample database, and shows how these classes are decorated with serialization attributes.

// 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 la clase Order del ejemplo siguiente, por brevedad solo se muestra la propiedad de asociación inversa que corresponde a la clase Customer.For the Order class in the following example, only the reverse association property corresponding to the Customer class is shown for brevity. No tiene un atributo DataMemberAttribute para evitar un ciclo.It does not have a DataMemberAttribute attribute to avoid a cycle.

// 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

Cómo serializar entidadesHow to Serialize the Entities

Puede serializar las entidades del código que se incluía en la sección anterior de la manera siguiente:You can serialize the entities in the codes shown in the previous section as follows;

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()

Relaciones auto-recursivasSelf-Recursive Relationships

Las relaciones auto-recursivas siguen el mismo patrón.Self-recursive relationships follow the same pattern. La propiedad de asociación que corresponde a la clave externa no tiene un atributo DataMemberAttribute, mientras que la propiedad primaria sí lo tiene.The association property corresponding to the foreign key does not have a DataMemberAttribute attribute, whereas the parent property does.

Tenga en cuenta la siguiente clase que tiene dos relaciones auto-recursivas: Employee.Manager y Employee.mentor/mentees.Consider the following class that has two self-recursive relationships: Employee.Manager/Reports and Employee.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)

Vea tambiénSee also