Procedura: mappare le relazioni di database (LINQ to SQL)

Qualsiasi relazione tra i dati, che rimane prevedibilmente sempre la stessa, può essere codificata come riferimenti alla proprietà nella classe di entità. Nel database di esempio Northwind, ad esempio, poiché in genere i clienti effettuano ordini, nel modello è sempre presente una relazione tra clienti e ordini.

In LINQ to SQL viene definito un attributo AssociationAttribute per consentire di rappresentare tali relazioni. Questo attributo viene utilizzato insieme ai tipi EntitySet<TEntity> e EntityRef<TEntity> per rappresentare quello che in un database sarebbe una relazione di chiave esterna. Per ulteriori informazioni, vedere la sezione relativa all'attributo Association di Mapping basato su attributo (LINQ to SQL).

NotaNota

I valori delle proprietà di archiviazione AssociationAttribute e ColumnAttribute rispettano la distinzione tra maiuscole e minuscole.Verificare, ad esempio, che per i valori dell'attributo della proprietà AssociationAttribute.Storage venga utilizzata la stessa combinazione di maiuscole e minuscole adoperata per i nomi di proprietà corrispondenti utilizzati in altri punti del codice.Ciò si applica a tutti i linguaggi di programmazione .NET, anche a quelli che in genere non distinguono tra maiuscole e minuscole, tra cui Visual Basic.Per ulteriori informazioni sulla proprietà di archiviazione, vedere DataAttribute.Storage.

La maggior parte delle relazioni è di tipo uno-a-molti, come nell'esempio riportato più avanti in questo argomento. È inoltre possibile rappresentare relazioni uno-a-uno e molti-a-molti come segue:

  • Uno-a-uno: per rappresentare questo tipo di relazione includere EntitySet<TEntity> su entrambi i lati.

    Ad esempio, si consideri una relazione Customer-SecurityCode creata in modo che il codice di sicurezza del cliente non venga trovato nella tabella Customer e a cui solo le persone autorizzate possano accedere.

  • Molti-a-molti: in questo tipo di relazioni la chiave primaria della tabella di collegamento è spesso formata da una combinazione di chiavi esterne delle altre due tabelle.

    Ad esempio, si consideri una relazione molti-a-molti Employee-Project creata utilizzando la classe EmployeeProject della tabella di collegamento. In LINQ to SQL è necessario che tale relazione venga modellata utilizzando tre classi:Employee, Project e EmployeeProject. In questo caso la modifica della relazione tra Employee e Project può apparentemente richiedere un aggiornamento della chiave primaria di EmployeeProject. In questa situazione, tuttavia, è preferibile modellare la relazione eliminando una classe EmployeeProject esistente e creando una nuova classe EmployeeProject.

    NotaNota

    Le relazioni nei database relazionali vengono in genere modellate come valori di chiave esterna che fanno riferimento a chiavi primarie in altre tabelle.Per spostarsi tra di esse, associare in modo esplicito le due tabelle utilizzando un'operazione di join relazionale.

    Gli oggetti in LINQ to SQL, d'altra parte, fanno riferimento reciproco utilizzando riferimenti alle proprietà o raccolte di riferimenti in cui è possibile spostarsi utilizzando la notazione del punto.

Esempio

Nell'esempio uno-a-molti seguente, alla classe Customer è associata una proprietà che dichiara la relazione tra clienti e ordini. La proprietà Orders è di tipo EntitySet<TEntity>. Questo tipo significa che si tratta di una relazione uno-a-molti (un cliente a molti ordini). La proprietà OtherKey viene utilizzata per descrivere come viene eseguita questa associazione, ovvero specificando il nome della proprietà nella classe correlata che dovrà essere confrontata con questa. In questo esempio viene confrontata la proprietà CustomerID, esattamente come verrebbe confrontato il valore di tale colonna con un'operazione join in un database.

NotaNota

Se si utilizza Visual Studio, è possibile adoperare Object Relational Designer per creare un'associazione tra classi.

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

È inoltre possibile invertire la situazione. Anziché utilizzare la classe Customer per descrivere l'associazione tra clienti e ordini, è possibile utilizzare la classe Order. La classe Order utilizza il tipo EntityRef<TEntity> per descrivere la relazione con la classe Customer, come nell'esempio di codice seguente.

NotaNota

La classe EntityRef<TEntity> supporta il caricamento posticipato.Per ulteriori informazioni, vedere Caricamento rinviato e immediato (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; }
    }
}

Vedere anche

Concetti

Il modello a oggetti LINQ to SQL

Altre risorse

Procedura: personalizzare le classi di entità mediante l'editor del codice (LINQ to SQL)