SerializzazioneSerialization

Questo argomento viene descritto LINQ to SQLLINQ to SQL le funzionalità di serializzazione.This topic describes LINQ to SQLLINQ to SQL serialization capabilities. Nei paragrafi che seguono sono disponibili informazioni sull'aggiunta di serializzazione durante la generazione di codice in fase di progettazione e il comportamento di serializzazione delle classi LINQ to SQLLINQ to SQL in fase di esecuzione.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.

È possibile aggiungere codice di serializzazione in fase di progettazione usando uno dei metodi seguenti:You can add serialization code at design time by either of the following methods:

  • Nel Object Relational DesignerObject Relational Designer, modificare il modalità di serializzazione proprietà Unidirectional.In the Object Relational DesignerObject Relational Designer, change the Serialization Mode property to Unidirectional.

  • Nella riga di comando SQLMetal, aggiungere il /serialization opzione.On the SQLMetal command line, add the /serialization option. Per altre informazioni, vedere SqlMetal.exe (strumento per la generazione del codice).For more information, see SqlMetal.exe (Code Generation Tool).

PanoramicaOverview

Il codice generato da LINQ to SQLLINQ to SQL fornisce funzionalità di caricamento posticipato per impostazione predefinita.The code generated by LINQ to SQLLINQ to SQL provides deferred loading capabilities by default. Il caricamento posticipato è molto pratico al livello intermedio per il caricamento trasparente dei dati su richiesta,Deferred loading is very convenient on the mid-tier for transparent loading of data on demand. tuttavia risulta problematico per la serializzazione, in quanto il serializzatore attiva comunque il caricamento posticipato a prescindere che questo sia o meno il comportamento designato.However, it is problematic for serialization, because the serializer triggers deferred loading whether deferred loading is intended or not. In effetti, quando un oggetto è serializzato, viene serializzata la relativa chiusura transitiva in tutti i riferimenti in uscita con caricamento posticipato.In effect, when an object is serialized, its transitive closure under all outbound defer-loaded references is serialized.

Il LINQ to SQLLINQ to SQL funzionalità di serializzazione risolve questo problema, principalmente tramite due meccanismi:The LINQ to SQLLINQ to SQL serialization feature addresses this problem, primarily through two mechanisms:

DefinizioniDefinitions

  • Serializzatore DataContract: il serializzatore predefinito utilizzato dal componente di Windows Communication Framework (WCF) di .NET Framework 3.0 o versioni successive.DataContract serializer: Default serializer used by the Windows Communication Framework (WCF) component of the .NET Framework 3.0 or later versions.

  • Serializzazione unidirezionale: la versione serializzata di una classe che contiene solo una proprietà di associazione unidirezionale (per evitare un ciclo).Unidirectional serialization: The serialized version of a class that contains only a one-way association property (to avoid a cycle). Per convenzione, la proprietà sul lato padre di una relazione di chiave primaria-esterna è contrassegnata per la serializzazione.By convention, the property on the parent side of a primary-foreign key relationship is marked for serialization. L'altro lato in un'associazione bidirezionale non è serializzato.The other side in a bidirectional association is not serialized.

    La serializzazione unidirezionale è il solo tipo di serializzazione supportato da LINQ to SQLLINQ to SQL.Unidirectional serialization is the only type of serialization supported by LINQ to SQLLINQ to SQL.

Esempio di codiceCode Example

Nel codice seguente vengono usate le classi Customer e Order tradizionali del database di esempio Northwind e viene descritto in che modo queste classi vengono decorate con gli attributi di serializzazione.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

Per la classe Order nell'esempio seguente viene illustrata per brevità solo la proprietà di associazione inversa che corrisponde alla classe Customer.For the Order class in the following example, only the reverse association property corresponding to the Customer class is shown for brevity. Questa classe non dispone di un attributo DataMember per evitare un ciclo.It does not have a DataMember 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

Come serializzare le entitàHow to Serialize the Entities

È possibile serializzare le entità nei codici riportati nella sezione precedente come segue: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()

Relazioni autoricorsiveSelf-Recursive Relationships

Le relazioni autoricorsive seguono lo stesso modello.Self-recursive relationships follow the same pattern. La proprietà di associazione che corrisponde alla chiave esterna non dispone di un attributo DataMember, che invece è disponibile nella proprietà padre.The association property corresponding to the foreign key does not have a DataMember attribute, whereas the parent property does.

Considerare la classe seguente che dispone di due relazioni autoricorsive: Employee.Manager/Reports e 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)

Vedere ancheSee Also

Informazioni di baseBackground Information
SqlMetal.exe (strumento per la generazione del codice)SqlMetal.exe (Code Generation Tool)
Procedura: rendere serializzabili le entitàHow to: Make Entities Serializable