如何:對應資料庫關聯性

您可以將任何永遠相同的資料關聯性 (Relationship),編碼成為實體類別 (Entity Class) 中的屬性參考。 例如,在 Northwind 範例資料庫中,因為客戶往往會下單,所以模型中的客戶與其訂單之間一定有關聯性。

LINQ to SQL 會定義 AssociationAttribute 屬性來協助表示這類關聯性。 這個屬性會與 EntitySet<TEntity>EntityRef<TEntity> 型別一起使用,以表示資料庫中的外部索引鍵關聯性為何。 如需詳細資訊,請參閱屬性架構對應的「關聯屬性」一節。

注意

AssociationAttribute 和 ColumnAttribute Storage 屬性值會區分大小寫。 例如,請確定用於 AssociationAttribute.Storage 屬性 (Property) 之屬性 (Attribute) 中的值與用於程式碼中其他位置之對應屬性 (Property) 名稱的大小寫相符。 這適用於所有 .NET 程式設計語言,甚至是通常不區分大小寫,包括 Visual Basic。 如需 Storage 屬性的詳細資訊,請參閱 DataAttribute.Storage

如本主題後面的範例所示,大部分關聯性都是一對多關聯性 (One-To-Many Relationship)。 您也可以表示一對一關聯性 (One-To-One Relationship) 和多對多關聯性 (Many-To-Many Relationship),如下所示:

  • 一對一:同時在兩邊包含 EntitySet<TEntity>,以表示這種關聯性。

    例如,考慮建立 Customer-SecurityCode 關聯性,如此便無法在 Customer 資料表中找到客戶的安全碼,而只有獲得授權的人員才可存取。

  • 多對多:在多對多關聯性中,連結資料表 (又稱為聯合資料表) 的主索引鍵通常是由另外兩個資料表中的複合外部索引鍵所構成。

    例如,請考慮使用連結資料表 EmployeeProject 所構成的 Employee-Project 多對多關聯性。 LINQ to SQL 要求使用下列三個類別塑造此種關聯性:EmployeeProjectEmployeeProject。 在此情況下,變更 EmployeeProject 之間的關聯性,似乎需要更新主索引鍵 EmployeeProject。 但是,刪除現有的 EmployeeProject 再建立新的 EmployeeProject 時,其實最能模擬此種情況。

    注意

    關聯式資料庫中的關聯性通常會塑造成需參考其他資料表中主索引鍵的外部索引鍵值。 若要導覽其間,您可以使用關聯式聯結作業,明確地使兩個資料表產生關聯。

    另一方面,LINQ to SQL 中的物件會使用您以標記法導覽的屬性參考或參考集合來互相參考。

範例 1

在下列一對多範例中,Customer 類別有個屬性會宣告客戶與其訂單之間的關聯性。 Orders 屬性是 EntitySet<TEntity> 型別。 這種型別表示這種關聯性為一對多 (一個客戶對多個訂單) 的關聯性。 OtherKey 屬性用於描述如何達成此種關聯,那就是指定相關類別中的屬性名稱與這個屬性名稱進行比較。 在此範例中,會比較 CustomerID 屬性,就像資料庫聯結會比較該資料行值一樣。

注意

如果您使用 Visual Studio,可以使用物件關聯式設計工具來建立類別之間的關聯。

[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

範例 2

您也可以反轉這種情況。 您可以使用 Customer 類別,而不要使用 Order 類別來描述客戶和訂單之間的關聯。 Order 類別會使用 EntityRef<TEntity> 型別來描述客戶的反向關聯性,如下列程式碼範例所示。

注意

EntityRef<TEntity> 類別可支援延後載入。 如需詳細資訊,請參閱延後和立即載入的比較

[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

另請參閱