LINQ to SQL'de Serileştirme
Bu makalede LINQ to SQL serileştirme özellikleri açıklanmaktadır. Aşağıdaki paragraflar, tasarım zamanında kod oluşturma sırasında serileştirme ekleme ve LINQ'nin SQL sınıflarına çalışma zamanı serileştirme davranışı hakkında bilgi sağlar.
Aşağıdaki yöntemlerden birini kullanarak tasarım zamanında serileştirme kodu ekleyebilirsiniz:
Nesne İlişkisel Tasarımcısı Serileştirme Modu özelliğini Tek Yönlü olarak değiştirin.
SQLMetal komut satırına /serialization seçeneğini ekleyin. Daha fazla bilgi için bkz . SqlMetal.exe (Kod Oluşturma Aracı).
Genel bakış
LINQ tarafından SQL'e oluşturulan kod varsayılan olarak ertelenen yükleme özellikleri sağlar. Ertelenmiş yükleme, verilerin isteğe bağlı olarak saydam olarak yüklenmesi için orta katmanda çok kullanışlıdır. Ancak, seri hale getirme işlemi, ertelenmiş yüklemenin amaçlanıp amaçlanmadığı farketmeksizin ertelenmiş yüklemeyi tetiklediğinden, seri hale getirme için sorunludur. Aslında, bir nesne seri hale getirildiğinde, giden ertelenmiş tüm başvurular altında geçişli kapanışı serileştirilir.
LINQ to SQL serileştirme özelliği öncelikle iki mekanizma aracılığıyla bu sorunu giderir:
DataContext Ertelenen yüklemeyi (ObjectTrackingEnabled) kapatmak için bir mod. Daha fazla bilgi için bkz. DataContext.
Oluşturulan varlıklarda ve System.Runtime.Serialization.DataMemberAttribute öznitelikleri oluşturmak System.Runtime.Serialization.DataContractAttribute için bir kod oluşturma anahtarı. Serileştirme altındaki sınıfların ertelenmesi davranışı da dahil olmak üzere bu yönü, bu konunun en önemli konusudur.
Tanımlar
DataContract seri hale getiricisi: .NET Framework 3.0 veya sonraki sürümlerin Windows Communication Framework (WCF) bileşeni tarafından kullanılan varsayılan seri hale getirici.
Tek yönlü serileştirme: Bir sınıfın yalnızca tek yönlü ilişkilendirme özelliği (döngüden kaçınmak için) içeren serileştirilmiş sürümü. Kural gereği, birincil-yabancı anahtar ilişkisinin üst tarafındaki özelliği serileştirme için işaretlenir. Çift yönlü ilişkilendirmenin diğer tarafı serileştirilmemiştir.
LINQ to SQL tarafından desteklenen tek seri hale getirme türü tek yönlü serileştirmedir.
Kod Örneği
Aşağıdaki kod, Northwind örnek veritabanındaki geleneksel Customer
ve Order
sınıflarını kullanır ve bu sınıfların serileştirme öznitelikleriyle nasıl dekore edilmiş olduğunu gösterir.
// 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
Aşağıdaki örnekteki sınıf için, yalnızca sınıfa Customer
karşılık gelen ters ilişkilendirme özelliği kısa için gösterilir. Döngüden kaçınmak için bir DataMemberAttribute özniteliği yoktur.
// 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
Varlıkları SeriLeştirme
Önceki bölümde gösterilen kodlardaki varlıkları aşağıdaki gibi seri hale getirebilirsiniz;
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()
Özyinelemeli İlişkiler
Özyinelemeli ilişkiler aynı deseni izler. Yabancı anahtara karşılık gelen ilişkilendirme özelliğinin özniteliği DataMemberAttribute yoktur, ancak üst özelliğin özniteliği yoktur.
İki özyinelemeli ilişkisi olan aşağıdaki sınıfı göz önünde bulundurun: Employee.Manager/Reports ve 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)