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 clasesCustomer
yOrder
.Crear y ejecutar una consulta para probar la obtención de información de
Order
mediante la claseCustomer
.
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
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); }
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;
.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
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) { } }
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();
Presione F5 para depurar la aplicación.
El resultado en la ventana Consola es:
ID=WHITC
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.