Tutorial: Realizar consultas en varias relaciones (C#)

En este tutorial, se muestra el uso de asociaciones de LINQ to SQL para representar relaciones de clave externa en la base de datos.

Nota:

Es posible que tu equipo muestre nombres o ubicaciones diferentes para algunos de los elementos de la interfaz de usuario de Visual Studio en las siguientes instrucciones. La edición de Visual Studio que se tenga y la configuración que se utilice determinan estos elementos. Para obtener más información, vea Personalizar el IDE.

Este tutorial se escribió con la configuración de desarrollo de Visual C#.

Requisitos previos

Debe haber completado el Tutorial: Modelo de objetos simple y consultas (C#). Este tutorial se basa en el tutorial mencionado, incluida la presencia del archivo northwnd.mdf en c:\linqtest5.

Información general

Este tutorial conlleva tres tareas principales:

  • Agregar una clase de entidad para representar la tabla Orders en la base de datos de ejemplo Northwind.

  • Complementar las anotaciones de la clase Customer para mejorar la relación entre las clases Customer y Order.

  • Crear y ejecutar una consulta para probar la obtención de información de Order mediante la clase Customer.

Asignar relaciones entre tablas

Después de la definición de la clase Customer, cree la definición de la clase de entidad Order, que incluye el código siguiente, que indica que Order.Customer se relaciona como clave externa con Customer.CustomerID.

Para agregar la clase de entidad Order

  • Escriba o pegue el código siguiente después de la clase 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; }
        }
    }
    

Anotar la clase Customer

En este paso, anotará la clase Customer para indicar su relación con la clase Order. (Esta adición no es estrictamente necesaria, porque para crear el vínculo basta con definir la relación en cualquier dirección. Sin embargo, al agregar esta anotación, se puede navegar con facilidad por los objetos en cualquier dirección).

Para anotar la clase Customer

  • Escriba o pegue el código siguiente en la clase 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); }
    }
    

Crear y ejecutar una consulta en la relación Customer-Order

Ahora puede tener acceso a los objetos Order directamente desde los objetos Customer, o a la inversa. No necesita una combinación explícita entre clientes y pedidos.

Para tener acceso a los objetos Order a través de los objetos Customer

  1. Modifique el método Main; para ello, escriba o pegue el código siguiente en el método:

    // 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. Presione F5 para depurar la aplicación.

    Nota

    Puede eliminar el código de SQL en la ventana Consola marcando como comentario db.Log = Console.Out;.

  3. Presione Entrar en la ventana Consola para detener la depuración.

Crear una vista de la base de datos fuertemente tipados

Es mucho más fácil empezar por una vista fuertemente tipada de la base de datos. Si el objeto DataContext está fuertemente tipado, no es necesario realizar llamadas a GetTable. Puede utilizar tablas fuertemente tipadas en todas sus consultas al utilizar el objeto DataContext fuertemente tipado.

En los pasos siguientes, creará Customers como una tabla fuertemente tipada que está asignada a la tabla Customers de la base de datos.

Para que el objeto DataContext esté fuertemente tipado

  1. Agregue el siguiente código encima de la declaración de la clase 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. Modifique el método Main para que utilice el objeto DataContext fuertemente tipado de la manera siguiente:

    // 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. Presione F5 para depurar la aplicación.

    El resultado en la ventana Consola es:

    ID=WHITC

  4. Presione Entrar en la ventana de la consola para detener la depuración.

Pasos siguientes

En el tutorial siguiente, Tutorial: Manipular datos (C#), se muestra cómo manipular los datos. Este tutorial no requiere que guarde los dos tutoriales ya completados de esta serie.

Consulte también