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 tableCustomer
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 liensEmployeeProject
. LINQ to SQL exige qu’une telle relation soit modélisée à l’aide de trois classes :Employee
,Project
etEmployeeProject
. Dans ce cas, la modification de la relation entreEmployee
etProject
peut sembler nécessiter une mise à jour de la clé primaireEmployeeProject
. Toutefois, la modélisation recommandée dans ce cas consiste à supprimer leEmployeeProject
existant et à créer un autreEmployeeProject
.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, consultez Comparaison 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