Udostępnij za pośrednictwem


Jak: Mapować relacje 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 w Mapowaniu opartym 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 zwykle nie rozróżniają 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ę, umieszczając EntitySet<TEntity> po obu stronach.

    Na przykład, rozważmy relację Customer-SecurityCode, która została utworzona, aby kod zabezpieczający klienta nie był znaleźć się w tabeli Customer i do której dostęp mają jedynie osoby autoryzowane.

  • 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 Employee a Project może wydawać się wymagać aktualizacji klucza EmployeeProjectpodstawowego . Jednak ta sytuacja najlepiej jest modelowana jako usunięcie istniejącego EmployeeProject i utworzenie nowego EmployeeProject.

    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 odnoszą się natomiast do siebie nawzajem, używając odniesień do właściwości lub kolekcji odniesień, które są nawigowane przy pomocy notacji kropkowej.

Przykład 1

W poniższym przykładzie klasa Customer jeden do wielu 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 typu EntityRef<TEntity> do opisania relacji z klientem, 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ż