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 w Customer 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 tabeli EmployeeProjectłączy . LinQ to SQL wymaga modelowania takiej relacji przy użyciu trzech klas: Employee, Projecti EmployeeProject. W takim przypadku zmiana relacji między elementem Project a Employee może wydawać się wymagać aktualizacji klucza EmployeeProjectpodstawowego . Jednak ta sytuacja jest najlepiej modelowana jako usunięcie istniejącej EmployeeProject i utworzenie nowego EmployeeProjectelementu .

    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ć relacyjnej Projektant obiektu, 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, zobaczOdroczone 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

Zobacz też