Procedura dettagliata: query tra relazioni (C#) (LINQ to SQL)

In questa procedura dettagliata viene descritto l'utilizzo delle associazioni LINQ to SQL per rappresentare relazioni di chiave esterna nel database.

NotaNota

Nel computer in uso è possibile che vengano visualizzati nomi o percorsi diversi per alcuni elementi dell'interfaccia utente di Visual Studio nelle istruzioni seguenti. La versione di Visual Studio in uso e le impostazioni configurate determinano questi elementi. Per ulteriori informazioni vedere Impostazioni di Visual Studio.

Questa procedura è stata scritta utilizzando Impostazioni di sviluppo di Visual C#.

Prerequisiti

È necessario avere completato la Procedura dettagliata: modello a oggetti e query semplici (C#) (LINQ to SQL). Questa procedura dettagliata si basa su tale procedura dettagliata, inclusa la presenza del file northwnd.mdf in c:\linqtest5.

Panoramica

La procedura dettagliata è costituita da tre attività principali:

  • Aggiunta di una classe di entità per rappresentare la tabella Orders nel database di esempio Northwind.

  • Completamento delle annotazioni alla classe Customer per migliorare la relazione tra le classi Customer e Order.

  • Creazione ed esecuzione di una query per testare la capacità di ottenere informazioni su Order utilizzando la classe Customer.

Esecuzione del mapping delle relazioni tra tabelle

Dopo la definizione della classe Customer, creare la definizione della classe di entità Order includendo il codice seguente per indicare che Order.Customer è correlata come chiave esterna a Customer.CustomerID.

Per aggiungere la classe di entità Order

  • Digitare o incollare il codice seguente dopo la classe Customer:

    [Table(Name = "Orders")]
    public class Order
    {
        private int _OrderID = 0;
        private string _CustomerID;
        private EntityRef<Customer> _Customer;
        public Order() { this._Customer = new EntityRef<Customer>(); }
    
        [Column(Storage = "_OrderID", DbType = "Int NOT NULL IDENTITY",
        IsPrimaryKey = true, IsDbGenerated = true)]
        public int OrderID
        {
            get { return this._OrderID; }
            // No need to specify a setter because IsDBGenerated is
            // true.
        }
    
        [Column(Storage = "_CustomerID", DbType = "NChar(5)")]
        public string CustomerID
        {
            get { return this._CustomerID; }
            set { this._CustomerID = value; }
        }
    
        [Association(Storage = "_Customer", ThisKey = "CustomerID")]
        public Customer Customer
        {
            get { return this._Customer.Entity; }
            set { this._Customer.Entity = value; }
        }
    }
    

Annotazione della classe Customer

In questo passaggio vengono aggiunte annotazioni alla classe Customer per indicare la relazione alla classe Order. Questa aggiunta non è strettamente necessaria, in quanto la definizione della relazione in una direzione è sufficiente per creare il collegamento. Tuttavia aggiungendo l'annotazione sarà possibile spostarsi facilmente tra gli oggetti in entrambe le direzioni.

Per annotare la classe Customer

  • Digitare o incollare il codice seguente nella classe Customer:

    private EntitySet<Order> _Orders;
    public Customer()
    {
        this._Orders = new EntitySet<Order>();
    }
    
    [Association(Storage = "_Orders", OtherKey = "CustomerID")]
    public EntitySet<Order> Orders
    {
        get { return this._Orders; }
        set { this._Orders.Assign(value); }
    }
    

Creazione ed esecuzione di un query sulla relazione Customer-Order

A questo punto è possibile accedere direttamente agli oggetti Order dagli oggetti Customer o viceversa. Non è necessario creare un join esplicito tra clienti e ordini.

Per accedere agli oggetti Order utilizzando oggetti Customer

  1. Modificare il metodo Main digitando o incollando il codice seguente nel metodo stesso:

    // Query for customers who have placed orders.
    var custQuery = 
        from cust in Customers
        where cust.Orders.Any()
        select cust;
    
    foreach (var custObj in custQuery)
    {
        Console.WriteLine("ID={0}, Qty={1}", custObj.CustomerID,
            custObj.Orders.Count);
    }
    
  2. Premere F5 per eseguire il debug dell'applicazione.

    NotaNota

    È possibile eliminare il codice SQL nella finestra della console impostando come commento db.Log = Console.Out;.

  3. Premere INVIO nella finestra della console per terminare il debug.

Creazione di una visualizzazione fortemente tipizzata del database

È molto più facile iniziare con una visualizzazione fortemente tipizzata del database. Applicando la tipizzazione forte all'oggetto DataContext, si eviterà di eseguire chiamate a GetTable. Quando si utilizza l'oggetto fortemente tipizzato DataContext, è possibile utilizzare tabelle fortemente tipizzate in tutte le query.

Nei passaggi seguenti si creerà Customers come tabella fortemente tipizzata mappata alla tabella Customers nel database.

Per tipizzare fortemente l'oggetto DataContext

  1. Aggiungere il codice riportato di seguito sopra la dichiarazione della classe Customer.

    public class Northwind : DataContext
    {
        // Table<T> abstracts database details per table/data type.
        public Table<Customer> Customers;
        public Table<Order> Orders;
    
        public Northwind(string connection) : base(connection) { }
    }
    
  2. Per utilizzare l'oggetto fortemente tipizzato DataContext, modificare il metodo Main come segue:

    // Use a connection string.
    Northwind db = new Northwind(@"C:\linqtest5\northwnd.mdf");
    
    // Query for customers from Seattle. 
    var custQuery =
        from cust in db.Customers
        where cust.City == "Seattle"
        select cust;
    
    foreach (var custObj in custQuery)
    {
        Console.WriteLine("ID={0}", custObj.CustomerID);
    }
    // Freeze the console window.
    Console.ReadLine();
    
  3. Premere F5 per eseguire il debug dell'applicazione.

    L'output nella finestra della console sarà:

    ID=WHITC

  4. Premere INVIO nella finestra della console per terminare il debug.

Passaggi successivi

Nella successiva procedura dettagliata, Procedura dettagliata: modifica dei dati (C#) (LINQ to SQL), verrà illustrato come modificare i dati. Per tale procedura dettagliata non è necessario avere salvato le due procedure dettagliate di questa serie già completate.

Vedere anche

Concetti

Apprendimento tramite le procedure dettagliate (LINQ to SQL)