Пошаговое руководство: Запросы по отношениям (C#)

В этом пошаговом руководстве показано использование связей LINQ to SQL для представления связей внешнего ключа в базе данных.

Примечание.

На компьютере могут отображаться различные имена или расположения для некоторых элементов пользовательского интерфейса Visual Studio в следующих инструкциях. Выпуск Visual Studio, который у вас есть, и параметры, которые вы используете, определяют эти элементы. Дополнительные сведения см. в разделе Персонализация интегрированной среды разработки.

Это пошаговое руководство было написано с помощью параметров разработки Visual C#.

Предпосылки

Необходимо выполнить пошаговое руководство. Простая объектная модель и запрос (C#). В этом пошаговом руководстве выполняется сборка этого файла, включая наличие файла northwnd.mdf в c:\linqtest5.

Обзор

Это пошаговое руководство состоит из трех основных задач:

  • Добавление класса сущности для представления таблицы Orders в примере базы данных Northwind.

  • Дополнение заметок к Customer классу для улучшения связи между Customer ними и Order классами.

  • Создание и выполнение запроса для тестирования получения Order информации с помощью Customer класса.

Сопоставление связей между таблицами

После определения класса Customer, создайте определение класса сущности Order, включающее следующий код, который указывает, что Order.Customer является внешним ключом для Customer.CustomerID.

Добавление класса сущности Order

  • Введите или вставьте следующий код после 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; }
        }
    }
    

Аннотирование класса клиента

На этом шаге вы заметите Customer класс, чтобы указать его связь с классом Order . (Это дополнение не является строго обязательным, так как определение связи в любом направлении достаточно для создания ссылки. Но добавление этой заметки позволяет легко перемещать объекты в любом направлении.)

Создание аннотации класса Customer

  • Введите или вставьте следующий код в 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); }
    }
    

Создание и выполнение запроса в рамках отношения Customer-Order

Теперь можно получить доступ к Order объектам непосредственно из Customer объектов или в противоположном порядке. Вам не требуется явная связь между клиентами и заказами.

Доступ к объектам Order с помощью объектов Customer

  1. Измените Main метод, введя или вставив следующий код в метод:

    // 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. Нажмите клавишу F5, чтобы отладить приложение.

    Примечание.

    Вы можете убрать код SQL в окне консоли, закомментировав db.Log = Console.Out;.

  3. Нажмите клавишу ВВОД в окне консоли, чтобы остановить отладку.

Создание строго типизированного представления базы данных

Гораздо проще начать с строго типизированного представления базы данных. При строгой типизации объекта DataContext не требуется вызовов GetTable. При использовании строго типизированного DataContext объекта можно использовать строго типизированные таблицы во всех запросах.

На следующих шагах вы создадите Customers в качестве строго типизированной таблицы, которая сопоставляется с таблицей Customers в базе данных.

Для строго типизации объекта DataContext

  1. Добавьте следующий код над объявлением 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. Измените Main метод, чтобы использовать строго типизированный DataContext метод следующим образом:

    // 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={custObj.CustomerID}");
    }
    // Freeze the console window.
    Console.ReadLine();
    
  3. Нажмите клавишу F5, чтобы отладить приложение.

    Выходные данные окна консоли:

    ID=WHITC

  4. Нажмите клавишу ВВОД в окне консоли, чтобы остановить отладку.

Дальнейшие шаги

В следующем пошаговом руководстве (пошаговое руководство. Управление данными (C#)) показано, как управлять данными. В этом пошаговом руководстве не требуется сохранять два пошаговых руководства из этой серии, которые вы уже выполнили.

См. также