方法 : データベース リレーションシップを割り当てる (LINQ to SQL)

データ リレーションシップが常に同じ場合は、これをエンティティ クラス内のプロパティ参照としてエンコードできます。 たとえば、Northwind サンプル データベースでは、通常は顧客が注文を発注するため、モデルには、顧客と注文のリレーションシップが常に存在します。

LINQ to SQL では、AssociationAttribute 属性を定義して、このようなリレーションシップを表します。 この属性を、EntitySet<TEntity> 型および EntityRef<TEntity> 型と共に使用すると、データベース内の外部キー リレーションシップに相当するものが表されます。詳細については、「属性ベースの対応付け (LINQ to SQL)」の「Association Attribute」セクションを参照してください。

メモメモ

AssociationAttribute プロパティ値と ColumnAttribute Storage プロパティ値では大文字と小文字が区別されます。たとえば、AssociationAttribute.Storage プロパティの属性に使用されている値は、コード内の別の場所で使用されている対応するプロパティ名と、大文字と小文字が一致するようにしてください。これは、Visual Basic など、通常は大文字と小文字が区別されない言語を含むすべての .NET プログラミング言語に適用されます。Storage プロパティの詳細については、「DataAttribute.Storage」を参照してください。

ほとんどのリレーションシップは、このトピックの例のように、一対多のリレーションシップです。 次に示すように、一対一および多対多のリレーションシップも表すことができます。

  • 一対一 : 両側に EntitySet<TEntity> を指定することによって、この種類のリレーションシップを表します。

    たとえば、顧客のセキュリティ コードが Customer テーブルには表示されず、承認されたユーザーのみがアクセスできるようにするために作成された、Customer-SecurityCode リレーションシップがその例です。

  • 多対多 : 多対多リレーションシップでは、リンク テーブル (結合テーブルともいいます) の主キーは、多くの場合、他の 2 つのテーブルの外部キーが結合して作成されます。

    たとえば、リンク テーブル EmployeeProject を使用して作成される Employee-Project という多対多リレーションシップがあるとします。 LINQ to SQL では、このようなリレーションシップを、Employee、Project、および EmployeeProject という 3 つのクラスを使用してモデル化する必要があります。 この場合、Employee と Project の間のリレーションシップを変更すると、主キーの EmployeeProject の更新が必要であるように見える可能性がありす。 ただし、この状態は、既存の EmployeeProject の削除、および新しい EmployeeProject の作成として適切にモデル化されます。

    メモメモ

    リレーショナル データベース内のリレーションシップは、通常、他のテーブルの主キーを参照する外部キー値としてモデル化されます。それらの間を移動するには、リレーショナル結合演算を使用して、2 つのテーブルを明示的に関連付けます。

    これに対して、LINQ to SQL 内のオブジェクトは、ドット表記を使用して移動するプロパティ参照または参照のコレクションを使用して、互いを参照します。

使用例

次の一対多の例では、Customer クラスは、顧客とその注文のリレーションシップを宣言するプロパティを持ちます。 Orders プロパティは EntitySet<TEntity> 型です。 この型は、このリレーションシップが一対多 (1 人の顧客対多くの注文) であることを意味します。 OtherKey プロパティを使用して、この関連付けを実現する方法を記述します。つまり、これと比較する、関連クラス内のプロパティの名前を指定します。 この例では、データベース結合がその列値を比較するときに、CustomerID プロパティが比較されます。

メモメモ

Visual Studio を使用している場合は、オブジェクト リレーショナル デザイナーを使用してクラス間の関連付けを作成できます。

<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
[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); }
    }
}

逆の場合も可能です。 Customer クラスを使用して顧客と注文の関連付けを記述するのではなく、Order クラスを使用できます。 Order クラスは、EntityRef<TEntity> 型を使用して、次のコード例に示すように、顧客へのリレーションシップを記述できます。

メモメモ

EntityRef<TEntity> クラスは、遅延読み込みをサポートします。詳細については、「遅延読み込みと即時読み込み (LINQ to SQL)」を参照してください。

<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
[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; }
    }
}

参照

概念

LINQ to SQL オブジェクト モデル

その他の技術情報

方法 : コード エディターを使用してエンティティ クラスをカスタマイズする (LINQ to SQL)