Comment : mapper des relations de base de données

Vous pouvez encoder comme références de propriété dans votre classe d'entité toutes les relations de données qui seront toujours fixes. Dans l'exemple de base de données Northwind, par exemple, comme les clients passent généralement des commandes, il existe toujours une relation dans le modèle entre les clients et leurs commandes.

LINQ to SQL définit un attribut AssociationAttribute pour faciliter la représentation de telles relations. Cet attribut est utilisé avec les types EntitySet<TEntity> et EntityRef<TEntity> pour représenter ce qui serait une relation de clé étrangère dans une base de données. Pour plus d’informations, consultez la section AssociationAttribute de la rubrique Mappage basé sur les attributs.

Notes

Les valeurs des propriétés AssociationAttribute et ColumnAttribute Storage respectent la casse. Assurez-vous, par exemple que les valeurs utilisées dans l'attribut de la propriété AssociationAttribute.Storage correspondent à la casse des noms de propriétés correspondants utilisés ailleurs dans le code. Cela s’applique à tous les langages de programmation .NET, y compris à ceux qui ne respectent généralement pas la casse, notamment Visual Basic. Pour plus d'informations sur la propriété Storage, consultez DataAttribute.Storage.

La plupart des relations sont de type un-à-plusieurs, comme dans l'exemple présenté ultérieurement dans cette rubrique. Vous pouvez également représenter les relations de type un-à-un et plusieurs à plusieurs comme suit :

  • Relation un-à-un : représentez ce type de relation en incluant EntitySet<TEntity> des deux côtés.

    Par exemple, considérons une relation Customer-SecurityCode créée afin que le code de sécurité du client ne soit pas trouvé dans la table Customer et que seules les personnes autorisées puissent y accéder.

  • Relations plusieurs à plusieurs : dans ce type de relations, la clé primaire de la table de liens (également nommée table de jointure) est souvent formée par une combinaison des clés étrangères des deux autres tables.

    Par exemple, considérons une relation Employee-Project de type plusieurs à plusieurs formée à l’aide de la table de liens EmployeeProject. LINQ to SQL exige qu’une telle relation soit modélisée à l’aide de trois classes : Employee, Project et EmployeeProject. Dans ce cas, la modification de la relation entre Employee et Project peut sembler nécessiter une mise à jour de la clé primaire EmployeeProject. Toutefois, la modélisation recommandée dans ce cas consiste à supprimer le EmployeeProject existant et à créer un autre EmployeeProject.

    Notes

    Les relations dans les bases de données relationnelles sont généralement modélisées comme des valeurs de clé étrangère qui font référence aux clés primaires d'autres tables. Pour naviguer entre elles, vous associez explicitement les deux tables en utilisant une opération de jointure relationnelle.

    En revanche, les objets de LINQ to SQL font référence les uns aux autres en utilisant les références de propriété ou de collection dans lesquelles vous naviguez à l'aide de la notation à points.

Exemple 1

Dans l'exemple un-à-plusieurs suivant, la classe Customer a une propriété qui déclare la relation entre les clients et leurs commandes. La propriété Orders est de type EntitySet<TEntity>. Ce type signifie que cette relation est de type un-à-plusieurs (un client et plusieurs commandes). La propriété OtherKey est utilisée pour décrire comment cette association est accomplie, à savoir, en spécifiant le nom de la propriété dans la classe connexe à comparer avec celle-ci. Dans cet exemple, la propriété CustomerID est comparée, comme une jointure de base de données serait comparée à cette valeur de colonne.

Notes

Si vous utilisez Visual Studio, vous pouvez utiliser le Concepteur Objet Relationnel pour créer une association entre les classes.

[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

Exemple 2

Vous pouvez également inverser la situation. Au lieu d'utiliser la classe Customer pour décrire l'association entre les clients et les commandes, vous pouvez utiliser la classe Order. La classe Order utilise le type EntityRef<TEntity> pour décrire la relation au client, comme dans l'exemple de code suivant.

Notes

La classe EntityRef<TEntity> prend en charge le chargement différé. Pour plus d’informations, consultezComparaison entre le chargement différé et le chargement immédiat.

[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

Voir aussi