Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel werden LINQ to SQL-Serialisierungsfunktionen beschrieben. Die folgenden Abschnitte enthalten Informationen zum Hinzufügen der Serialisierung während der Codeerstellung zur Entwurfszeit sowie zum Serialisierungsverhalten von LINQ to SQL-Klassen zur Laufzeit.
Sie können zur Entwurfszeit durch eine der folgenden Methoden Serialisierungscode hinzufügen:
Ändern Sie im Objektrelational-Designer die Serialisierungsmoduseigenschaft in "Unidirectional".
Fügen Sie in der Befehlszeile sqlMetal die Option "/serialisierung " hinzu. Weitere Informationen finden Sie unter SqlMetal.exe (Tool zur Codegenerierung).
Überblick
Der von LINQ to SQL generierte Code stellt standardmäßig verzögerte Ladefunktionen bereit. Verzögertes Laden ist sehr bequem auf der mittleren Ebene für das transparente Laden von Daten bei Bedarf. Für die Serialisierung ist es jedoch problematisch, da der Serialisierer verzögertes Laden auslöst, ob das verzögerte Laden beabsichtigt ist oder nicht. Wird ein Objekt serialisiert, wird sein transitiver Abschluss unter allen ausgehenden verzögert geladenen Verweisen serialisiert.
Das LINQ to SQL-Serialisierungsfeature behebt dieses Problem in erster Linie über zwei Mechanismen:
Ein DataContext Modus zum Deaktivieren des verzögerten Ladens (ObjectTrackingEnabled). Weitere Informationen finden Sie unter DataContext.
Eine Codegenerierungsoption zum Generieren von System.Runtime.Serialization.DataContractAttribute- und System.Runtime.Serialization.DataMemberAttribute-Attributen bei generierten Entitäten. Dieser Aspekt, einschließlich des Verhaltens von Klassen zum verzögerten Laden im Rahmen der Serialisierung, ist das Hauptthema dieses Abschnitts.
Definitionen
DataContract Serializer: Standard serialisierer, der von der Windows Communication Framework (WCF)-Komponente der .NET Framework 3.0- oder höher-Versionen verwendet wird.
Unidirektionale Serialisierung: Die serialisierte Version einer Klasse, die nur eine unidirektionale Zuordnungseigenschaft enthält (um einen Zyklus zu vermeiden). Laut Konvention wird die Eigenschaft auf der übergeordneten Seite einer primären Fremdschlüsselbeziehung für die Serialisierung markiert. Die andere Seite in einer bidirektionalen Zuordnung wird nicht serialisiert.
Die unidirektionale Serialisierung ist der einzige Typ der Serialisierung, der von LINQ to SQL unterstützt wird.
Codebeispiel
Der folgende Code verwendet die herkömmlichen Customer
Klassen und Order
Klassen aus der Northwind-Beispieldatenbank und zeigt, wie diese Klassen mit Serialisierungsattributen versehen werden.
// 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
Für die Order
Klasse im folgenden Beispiel wird nur die umgekehrte Zuordnungseigenschaft, die der Customer
Klasse entspricht, aus Platzgründen angezeigt. Es verfügt nicht über ein DataMemberAttribute Attribut, um einen Zyklus zu vermeiden.
// 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
So serialisieren Sie die Entitäten
Sie können die Entitäten in den im vorherigen Abschnitt gezeigten Codes wie folgt serialisieren.
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()
Selbstrekursive Beziehungen
Selbst rekursive Beziehungen folgen demselben Muster. Die Zuordnungseigenschaft, die dem Fremdschlüssel entspricht, besitzt kein DataMemberAttribute-Attribut, während die übergeordnete Eigenschaft eines besitzt.
Betrachten Sie die folgende Klasse mit zwei selbstrekursiven Beziehungen: Employee.Manager/Reports und 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)