Instrukcje: mapowania relacji bazy danych
Można kodować jako odwołania do właściwości w klasie jednostki wszelkie relacje danych, które zawsze będą takie same. Na przykład w przykładowej bazie danych Northwind, ponieważ klienci zazwyczaj składają zamówienia, zawsze istnieje relacja między klientami a ich zamówieniami.
LINQ to SQL definiuje AssociationAttribute atrybut, który pomaga reprezentować takie relacje. Ten atrybut jest używany razem z typami EntitySet<TEntity> i EntityRef<TEntity> do reprezentowania relacji klucza obcego w bazie danych. Aby uzyskać więcej informacji, zobacz sekcję Atrybut skojarzenia mapowania opartego na atrybutach.
Uwaga
W wartościach właściwości AssociationAttribute i ColumnAttribute Storage uwzględniana jest wielkość liter. Na przykład upewnij się, że wartości używane w atrybucie właściwości AssociationAttribute.Storage są zgodne z wielkością liter odpowiednich nazw właściwości używanych w innym miejscu w kodzie. Dotyczy to wszystkich języków programowania .NET, nawet tych, które nie są zwykle uwzględniane wielkości liter, w tym Visual Basic. Aby uzyskać więcej informacji na temat właściwości Storage, zobacz DataAttribute.Storage.
Większość relacji to jeden do wielu, jak w przykładzie w dalszej części tego tematu. Można również reprezentować relacje jeden do jednego i wiele do wielu w następujący sposób:
Jeden do jednego: reprezentują tego rodzaju relację, włączając EntitySet<TEntity> je po obu stronach.
Rozważmy na przykład relację utworzoną
Customer
-SecurityCode
, aby kod zabezpieczeń klienta nie został znaleziony wCustomer
tabeli i można uzyskać do niego dostęp tylko przez autoryzowane osoby.Wiele do wielu: W relacjach wiele-do-wielu klucz podstawowy tabeli łączy (nazywanej również tabelą skrzyżowań ) jest często tworzony przez złożone klucze obce z pozostałych dwóch tabel.
Rozważmy na przykład relację wiele-do-wielu utworzoną
Employee
-Project
przy użyciu tabeliEmployeeProject
łączy . LinQ to SQL wymaga modelowania takiej relacji przy użyciu trzech klas:Employee
,Project
iEmployeeProject
. W takim przypadku zmiana relacji między elementemProject
aEmployee
może wydawać się wymagać aktualizacji kluczaEmployeeProject
podstawowego . Jednak ta sytuacja jest najlepiej modelowana jako usunięcie istniejącejEmployeeProject
i utworzenie nowegoEmployeeProject
elementu .Uwaga
Relacje w relacyjnych bazach danych są zwykle modelowane jako wartości kluczy obcych, które odwołują się do kluczy podstawowych w innych tabelach. Aby przejść między nimi, jawnie skojarzysz dwie tabele przy użyciu operacji sprzężenia relacyjnego.
Obiekty w linQ to SQL, z drugiej strony, odwołują się do siebie przy użyciu odwołań właściwości lub kolekcji odwołań, które są nawigowane przy użyciu notacji kropkowej .
Przykład 1
W poniższym przykładzie Customer
jeden do wielu klasa ma właściwość, która deklaruje relację między klientami a ich zamówieniami. Właściwość Orders
jest typu EntitySet<TEntity>. Ten typ oznacza, że ta relacja to jeden do wielu (jeden klient do wielu zamówień). Właściwość OtherKey służy do opisywania sposobu wykonania tego skojarzenia, a mianowicie przez określenie nazwy właściwości w powiązanej klasie, która ma być porównywana z tą klasą. W tym przykładzie właściwość jest porównywanaCustomerID
, podobnie jak sprzężenie bazy danych porównuje tę wartość kolumny.
Uwaga
Jeśli używasz programu Visual Studio, możesz użyć Projektanta relacyjnego obiektów, aby utworzyć skojarzenie między klasami.
[Table(Name = "Customers")]
public partial class Customer
{
[Column(IsPrimaryKey = true)]
public string CustomerID;
// ...
private EntitySet<Order> _Orders;
[Association(Storage = "_Orders", OtherKey = "CustomerID")]
public EntitySet<Order> Orders
{
get { return this._Orders; }
set { this._Orders.Assign(value); }
}
}
<Table(Name:="Customers")> _
Public Class Customer
<Column(IsPrimaryKey:=True)> _
Public CustomerID As String
' ...
Private _Orders As EntitySet(Of Order)
<Association(Storage:="_Orders", OtherKey:="CustomerID")> _
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
End Class
Przykład 2
Można również odwrócić sytuację. Zamiast używać Customer
klasy do opisywania skojarzenia między klientami i zamówieniami, można użyć Order
klasy . Klasa Order
używa EntityRef<TEntity> typu , aby opisać relację z powrotem do klienta, jak w poniższym przykładzie kodu.
Uwaga
Klasa EntityRef<TEntity> obsługuje odroczone ładowanie. Aby uzyskać więcej informacji, zobacz Odroczone i Bezpośrednie ładowanie.
[Table(Name = "Orders")]
public class Order
{
[Column(IsPrimaryKey = true)]
public int OrderID;
[Column]
public string CustomerID;
private EntityRef<Customer> _Customer;
[Association(Storage = "_Customer", ThisKey = "CustomerID")]
public Customer Customer
{
get { return this._Customer.Entity; }
set { this._Customer.Entity = value; }
}
}
<Table(Name:="Orders")> _
Public Class Order
<Column(IsPrimaryKey:=True)> _
Public OrderID As Integer
<Column()> _
Public CustomerID As String
Private _Customer As EntityRef(Of Customer)
<Association(Storage:="Customer", ThisKey:="CustomerID")> _
Public Property Customer() As Customer
Get
Return Me._Customer.Entity
End Get
Set(ByVal value As Customer)
Me._Customer.Entity = value
End Set
End Property
End Class