Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek popisuje možnosti serializace LINQ to SQL. Následující odstavce poskytují informace o tom, jak přidat serializaci během generování kódu v době návrhu a o chování serializace modulu runtime tříd LINQ to SQL.
Kód serializace můžete přidat v době návrhu některou z následujících metod:
V Návrháři relační objektu změňte vlastnost Režim serializace na Jednosměrný.
Na příkazovém řádku SQLMetal přidejte možnost /serializace . Další informace najdete v tématu SqlMetal.exe (nástroj pro generování kódu).
Přehled
Kód vygenerovaný jazykem LINQ to SQL poskytuje ve výchozím nastavení možnosti odloženého načítání. Odložené načítání je velmi pohodlné na střední vrstvě pro transparentní načítání dat na vyžádání. Je však problematické pro serializaci, protože serializátor aktivuje odložené načítání bez ohledu na to, zda je odložené načítání zamýšleno, nebo ne. Pokud je objekt serializován, pak je také serializováno jeho tranzitivní uzávěr nad všemi odchozími referencemi, které jsou načítány později.
Funkce serializace LINQ to SQL řeší tento problém, a to především prostřednictvím dvou mechanismů:
Režim DataContext pro vypnutí odloženého načítání (ObjectTrackingEnabled). Další informace najdete v tématu DataContext.
Přepínač generování kódu pro vygenerování atributů System.Runtime.Serialization.DataContractAttribute a System.Runtime.Serialization.DataMemberAttribute na generovaných entitách. Tento aspekt, včetně chování tříd s odloženým načítáním v rámci serializace, je hlavním předmětem tohoto tématu.
Definice
DataContract serializátor: Výchozí serializátor používaný komponentem Windows Communication Foundation (WCF) rozhraní .NET Framework 3.0 nebo novějších verzí.
Jednosměrná serializace: Serializovaná verze třídy, která obsahuje pouze jednosměrnou vlastnost přidružení (aby se zabránilo cyklu). Podle konvence je vlastnost na nadřazené straně vztahu primárního cizího klíče označena pro serializaci. Opačná strana obousměrného přidružení není serializována.
Jednosměrná serializace je jediným typem serializace, kterou podporuje LINQ to SQL.
Příklad kódu
Následující kód používá Customer a Order tradiční třídy z ukázkové databáze Northwind a ukazuje, jak jsou tyto třídy ozdobeny serializačními atributy.
// 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
Order Pro třídu v následujícím příkladu je zobrazena pouze zpětná asociační vlastnost odpovídající Customer třídě pro stručnost. Nemá atribut DataMemberAttribute, aby se zabránilo cyklu.
// 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
Jak serializovat entity
Entity v kódech zobrazených v předchozí části můžete serializovat následujícím způsobem;
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 Vztahy
Sebe-rekurzivní vztahy se řídí stejným vzorem. Vlastnost přidružení odpovídající cizímu klíči nemá DataMemberAttribute atribut, zatímco nadřazená vlastnost má.
Vezměte v úvahu následující třídu, která má dvě sebe rekurzivní vztahy: Employee.Manager/Reports a 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)