Обновление адаптера таблицы TableAdapter для использования JOIN (C#)

Скотт Митчелл

Загрузить PDF-файл

При работе с базой данных обычно запрашивают данные, распределенные между несколькими таблицами. Для получения данных из двух разных таблиц можно использовать связанный вложенный запрос или операцию JOIN. В этом руководстве мы сравниваем коррелированные вложенные запросы и синтаксис JOIN, прежде чем рассматривать, как создать TableAdapter, который включает JOIN в запрос main.

Введение

В реляционных базах данных данные, с которыми мы хотим работать, часто распределяются между несколькими таблицами. Например, при отображении сведений о продукте мы, скорее всего, хотим перечислить соответствующие категории продуктов и названия поставщиков. Таблица Products содержит CategoryID значения и SupplierID , но фактические имена категорий и поставщиков находятся в Categories таблицах и Suppliers соответственно.

Чтобы получить сведения из другой связанной таблицы, можно использовать коррелированные вложенные запросы или JOINs. Коррелированные вложенные запросы — это вложенный запрос, который ссылается SELECT на столбцы во внешнем запросе. Например, в учебнике Создание уровня доступа к данным мы использовали два коррелированных вложенных запроса в ProductsTableAdapter запросе main для возврата категорий и имен поставщиков для каждого продукта. — JOIN это конструкция SQL, которая объединяет связанные строки из двух разных таблиц. Мы использовали в руководстве По запросу данных с элементомJOIN управления SqlDataSource для отображения сведений о категориях вместе с каждым продуктом.

Причина, по которой мы воздержались от использования JOIN объектов с TableAdapters, связана с ограничениями мастера TableAdapter для автоматического создания соответствующих INSERTинструкций , UPDATEи DELETE . В частности, если запрос main TableAdapter содержит какие-либо JOIN , tableAdapter не может автоматически создать нерегламентированные инструкции SQL или хранимые процедуры для своих InsertCommandсвойств , UpdateCommandи DeleteCommand .

В этом руководстве мы кратко сравним и сопоставим коррелированные вложенные запросы и JOIN запросы, прежде чем изучить, как создать TableAdapter, включающий JOIN в main запрос.

Сравнение и контрастирование коррелированных вложенных запросов иJOIN

Помните, что ProductsTableAdapter созданный в первом учебнике в Northwind DataSet использует коррелированные вложенные запросы для возврата каждой соответствующей категории и имени поставщика каждого продукта. Запрос ProductsTableAdapter main показан ниже.

SELECT ProductID, ProductName, SupplierID, CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = 
            Products.CategoryID) as CategoryName, 
       (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = 
            Products.SupplierID) as SupplierName
FROM Products

Два коррелированных вложенных запроса - (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID) и (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) - являются SELECT запросами, которые возвращают одно значение для каждого продукта в качестве дополнительного столбца в списке столбцов внешней SELECT инструкции.

Кроме того, JOIN можно использовать для возврата названия поставщика и категории каждого продукта. Следующий запрос возвращает те же выходные данные, что и приведенный выше, но вместо вложенных запросов использует JOIN s:

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

Объединяет JOIN записи из одной таблицы с записями из другой таблицы на основе некоторых критериев. В приведенном выше запросе, например, LEFT JOIN Categories ON Categories.CategoryID = Products.CategoryID указывает SQL Server объединить каждую запись продукта с записью категории, значение которой CategoryID соответствует значению продуктаCategoryID. Объединенный результат позволяет работать с соответствующими полями категорий для каждого продукта (например CategoryName, ).

Примечание

JOIN обычно используются при запросе данных из реляционных баз данных. Если вы не знакомы с синтаксисом JOIN или хотите немного освежить его использование, я рекомендую руководство по присоединению к SQL в W3 Schools. Кроме того, стоит ознакомиться с JOIN разделами Основы и Основы вложенных запросовэлектронной документации по SQL.

Так как JOIN s и связанные вложенные запросы можно использовать для получения связанных данных из других таблиц, многие разработчики остаются в голове и задаются вопросом, какой подход использовать. Все гуру SQL, с которыми я говорил, говорили примерно то же самое, что это не имеет значения для производительности, так как SQL Server будет производить примерно одинаковые планы выполнения. Их совет, таким образом, заключается в том, чтобы использовать технику, которая вам и вашей команде наиболее комфортно. Стоит отметить, что после того, как эти советы эти эксперты немедленно выражают свое предпочтение s JOIN по сравнению с коррелированные вложенные запросы.

При создании уровня доступа к данным с помощью типизированных наборов данных средства лучше работают при использовании вложенных запросов. В частности, мастер TableAdapter не будет автоматически создавать соответствующие INSERTинструкции , и DELETE , UPDATEесли запрос main содержит какие-либо JOIN s, но будет автоматически создавать эти инструкции при использовании коррелированных вложенных запросов.

Чтобы изучить этот недостаток, создайте временный типизированный набор данных в папке ~/App_Code/DAL . В мастере настройки TableAdapter выберите использование нерегламентированных инструкций SQL и введите следующий SELECT запрос (см. рис. 1):

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

Снимок экрана: окно мастера настройки TableAdaptor с введенным запросом, содержащим имена JOIN.

Рис. 1. Ввод основного запроса, содержащего JOIN s (щелкните для просмотра полноразмерного изображения)

По умолчанию TableAdapter автоматически создает INSERTинструкции , UPDATEи DELETE на основе запроса main. Если нажать кнопку Дополнительно, вы увидите, что эта функция включена. Несмотря на этот параметр, TableAdapter не сможет создать инструкции INSERT, и DELETE , UPDATEтак как запрос main содержит JOIN.

Снимок экрана: окно

Рис. 2. Ввод основного запроса, содержащего JOIN s

Чтобы завершить работу мастера, нажмите кнопку Готово. На этом этапе Designer DataSet будет содержать один объект TableAdapter с таблицей DataTable со столбцами для каждого поля, возвращаемого в списке SELECT столбцов запроса. Сюда входят и SupplierName, как показано на CategoryName рисунке 3.

DataTable содержит столбец для каждого поля, возвращаемого в списке столбцов

Рис. 3. DataTable содержит столбец для каждого поля, возвращаемого в списке столбцов

Хотя Таблица Данных содержит соответствующие столбцы, tableAdapter не имеет значений для свойств InsertCommand, UpdateCommandи DeleteCommand . Чтобы подтвердить это, щелкните TableAdapter в Designer и перейдите к окно свойств. Там вы увидите InsertCommand, что свойства , UpdateCommandи DeleteCommand имеют значение (None) .

Свойства InsertCommand, UpdateCommand и DeleteCommand имеют значение (Нет)

Рис. 4. Свойства InsertCommand, UpdateCommandи DeleteCommand имеют значение (нет) (щелкните для просмотра полноразмерного изображения)

Чтобы обойти этот недостаток, можно вручную предоставить инструкции и параметры SQL для InsertCommandсвойств , UpdateCommandи DeleteCommand с помощью окно свойств. Кроме того, можно начать с настройки запроса main TableAdapter так, чтобы они не включали.JOIN Это позволит INSERTавтоматически создавать операторы , UPDATEи DELETE . После завершения работы мастера можно вручную обновить tableAdapter SelectCommand из окно свойств, чтобы он включает JOIN синтаксис.

Хотя этот подход работает, он очень хрупкий при использовании нерегламентированных SQL-запросов, так как каждый раз, когда запрос main TableAdapter повторно настраивается с помощью мастера, автоматически созданные INSERTинструкции , UPDATEи DELETE создаются повторно. Это означает, что все внесенные позже настройки будут потеряны, если щелкнуть правой кнопкой мыши tableAdapter, выбрать в контекстном меню пункт Настроить и снова завершить работу мастера.

К счастью, хрупкость автоматически создаваемых INSERTинструкций TableAdapter , UPDATEи DELETE ограничена нерегламентированными инструкциями SQL. Если tableAdapter использует хранимые процедуры, можно настроить SelectCommandхранимые процедуры , InsertCommand, UpdateCommandили DeleteCommand и повторно запустить мастер настройки TableAdapter, не опасаясь, что хранимые процедуры будут изменены.

В течение следующих нескольких шагов мы создадим TableAdapter, который изначально использует запрос main, который пропускает любые JOIN s, чтобы соответствующие хранимые процедуры вставки, обновления и удаления были созданы автоматически. Затем мы обновим SelectCommand , чтобы использовать JOIN , который возвращает дополнительные столбцы из связанных таблиц. Наконец, мы создадим соответствующий класс уровня бизнес-логики и продемонстрируем использование TableAdapter на веб-странице ASP.NET.

Шаг 1. Создание объекта TableAdapter с помощью упрощенного основного запроса

В этом руководстве мы добавим TableAdapter и строго типизированную таблицу Employees DataTable для таблицы в NorthwindWithSprocs DataSet. Таблица Employees содержит ReportsTo поле, указывающее EmployeeID для руководителя сотрудника. Например, сотрудник Энн Додсворт имеет ReportTo значение 5, которое является стивеном EmployeeID Бьюкененом. Следовательно, Энн докладывает Стивену, ее менеджеру. Наряду с отчетом о значении ReportsTo каждого сотрудника, мы также можем получить имя его руководителя. Это можно сделать с помощью JOIN. Однако использование при первоначальном JOIN создании TableAdapter не позволяет мастеру автоматически создавать соответствующие возможности вставки, обновления и удаления. Поэтому мы начнем с создания TableAdapter, запрос main которого не содержит sJOIN. Затем на шаге 2 мы обновим хранимую процедуру запроса main, чтобы получить имя руководителя с помощью JOIN.

Начните с NorthwindWithSprocs открытия DataSet в папке ~/App_Code/DAL . Щелкните правой кнопкой мыши Designer, выберите в контекстном меню пункт Добавить и выберите пункт меню TableAdapter. Откроется мастер настройки TableAdapter. Как показано на рисунке 5, мастер должен создать новые хранимые процедуры и нажать кнопку Далее. Дополнительные сведения о создании новых хранимых процедур из мастера TableAdapter см. в руководстве Создание новых хранимых процедур для Typed DataSet s TableAdapters .

Выберите параметр Create new stored procedures (Создать хранимые процедуры).

Рис. 5. Выбор параметра "Создать новые хранимые процедуры" (щелкните для просмотра полноразмерного изображения)

Используйте следующую SELECT инструкцию для запроса main TableAdapter:

SELECT EmployeeID, LastName, FirstName, Title, HireDate, ReportsTo, Country
FROM Employees

Так как этот запрос не содержит sJOIN, мастер TableAdapter автоматически создаст хранимые процедуры с соответствующими INSERTоператорами , UPDATEи DELETE , а также хранимую процедуру для выполнения запроса main.

Следующий шаг позволяет присвоить имя хранимым процедурам TableAdapter. Используйте имена Employees_Select, Employees_Insert, Employees_Updateи Employees_Delete, как показано на рисунке 6.

Назовите хранимые процедуры TableAdapter

Рис. 6. Имя хранимых процедур TableAdapter (щелкните для просмотра полноразмерного изображения)

На последнем шаге предлагается присвоить имена методам TableAdapter. Используйте Fill и GetEmployees в качестве имен методов. Кроме того, не забудьте установить флажок Создать методы для отправки обновлений непосредственно в базу данных (GenerateDBDirectMethods).

Назовите методы TableAdapter Fill и GetEmployees

Рис. 7. Назовите методы Fill TableAdapter и GetEmployees (Щелкните для просмотра полноразмерного изображения)

После завершения работы мастера уделите некоторое время изучению хранимых процедур в базе данных. Вы увидите четыре новых: Employees_Select, Employees_Insert, Employees_Updateи Employees_Delete. Затем проверьте только что созданные EmployeesDataTable и EmployeesTableAdapter . DataTable содержит столбец для каждого поля, возвращаемого запросом main. Щелкните TableAdapter и перейдите к окно свойств. Там вы увидите InsertCommand, что свойства , UpdateCommandи DeleteCommand правильно настроены для вызова соответствующих хранимых процедур.

TableAdapter включает возможности вставки, обновления и удаления.

Рис. 8. TableAdapter включает возможности вставки, обновления и удаления (щелкните для просмотра полноразмерного изображения)

С автоматически созданными хранимыми процедурами вставки, обновления и удаления и InsertCommandправильно настроенными свойствами , UpdateCommandи DeleteCommand мы готовы настроить SelectCommand хранимую процедуру для возврата дополнительных сведений о каждом руководителе сотрудника. В частности, необходимо обновить хранимую Employees_SelectJOIN процедуру для использования и вернуть значения и значения диспетчера FirstNameLastName . После обновления хранимой процедуры необходимо обновить таблицу DataTable, чтобы она включила эти дополнительные столбцы. Мы рассмотрим эти две задачи на шагах 2 и 3.

Шаг 2. Настройка хранимой процедуры для включенияJOIN

Для начала перейдите к Обозреватель сервера, перейдите в папку Хранимых процедур базы данных Northwind и откройте хранимую Employees_Select процедуру. Если эта хранимая процедура не отображается, щелкните правой кнопкой мыши папку Хранимые процедуры и выберите Обновить. Обновите хранимую процедуру, чтобы она возвращала LEFT JOIN имя и фамилию руководителя:

SELECT Employees.EmployeeID, Employees.LastName, 
       Employees.FirstName, Employees.Title, 
       Employees.HireDate, Employees.ReportsTo, 
       Employees.Country,
       Manager.FirstName as ManagerFirstName, 
       Manager.LastName as ManagerLastName
FROM Employees
    LEFT JOIN Employees AS Manager ON
        Employees.ReportsTo = Manager.EmployeeID

После обновления инструкции SELECT сохраните изменения, перейдя в меню Файл и выбрав Сохранить Employees_Select. Кроме того, можно щелкнуть значок Сохранить на панели инструментов или нажать клавиши CTRL+S. После сохранения изменений щелкните правой кнопкой мыши хранимую Employees_Select процедуру в Обозреватель сервера и выберите команду Выполнить. При этом будет выполнена хранимая процедура и отобразятся ее результаты в окне Вывод (см. рис. 9).

Результаты хранимых процедур отображаются в окне вывода.

Рис. 9. Результаты хранимых процедур отображаются в окне вывода (щелкните для просмотра полноразмерного изображения)

Шаг 3. Обновление столбцов DataTable

На этом этапе хранимая Employees_Select процедура возвращает ManagerFirstName значения и ManagerLastName , но EmployeesDataTable в отсутствуют эти столбцы. Эти отсутствующие столбцы можно добавить в таблицу Данных одним из двух способов:

  • Вручную. Щелкните правой кнопкой мыши DataTable в Designer DataSet и в меню Добавить выберите Столбец. Затем можно присвоить столбцу имя и задать его свойства соответствующим образом.
  • Автоматически — мастер настройки TableAdapter обновит столбцы DataTable, чтобы отразить поля, возвращаемые хранимой SelectCommand процедурой. При использовании нерегламентированных инструкций SQL мастер также удалит InsertCommandсвойства , и DeleteCommand , UpdateCommandтак как SelectCommand теперь содержит JOIN. Но при использовании хранимых процедур эти свойства команд остаются неизменными.

В предыдущих руководствах мы рассмотрели добавление столбцов DataTable вручную, включая основные и подробные сведения с использованием маркированного списка главных записей с подробным списком данных и отправки файлов, и мы рассмотрим этот процесс более подробно в следующем руководстве. Однако в этом руководстве мы будем использовать автоматический подход с помощью мастера настройки TableAdapter.

Начните с щелчка правой кнопкой EmployeesTableAdapter мыши и выберите Пункт Настроить в контекстном меню. Откроется мастер настройки TableAdapter, в котором перечислены хранимые процедуры, используемые для выбора, вставки, обновления и удаления, а также возвращаемые значения и параметры (если таковые есть). На рисунке 10 показан этот мастер. Здесь видно, что хранимая Employees_Select процедура теперь возвращает ManagerFirstName поля и ManagerLastName .

Мастер отображает обновленный список столбцов для Employees_Select хранимой процедуры

Рис. 10. Мастер показывает обновленный список столбцов для хранимой Employees_Select процедуры (щелкните, чтобы просмотреть полноразмерное изображение)

Завершите работу мастера, нажав кнопку Готово. При возвращении к Designer EmployeesDataTable DataSet включает два дополнительных столбца: ManagerFirstName и ManagerLastName.

EmployeesDataTable содержит два новых столбца

Рис. 11. Содержит EmployeesDataTable два новых столбца (щелкните для просмотра полноразмерного изображения)

Чтобы продемонстрировать, что обновленная Employees_Select хранимая процедура действует и возможности вставки, обновления и удаления TableAdapter по-прежнему работают, создайте веб-страницу, позволяющую пользователям просматривать и удалять сотрудников. Однако перед созданием такой страницы необходимо сначала создать новый класс на уровне бизнес-логики для работы с сотрудниками из NorthwindWithSprocs DataSet. На шаге 4 мы создадим EmployeesBLLWithSprocs класс. На шаге 5 мы будем использовать этот класс со страницы ASP.NET.

Шаг 4. Реализация уровня бизнес-логики

Создайте файл класса в папке ~/App_Code/BLL с именем EmployeesBLLWithSprocs.cs. Этот класс имитирует семантику существующего EmployeesBLL класса, только новый класс предоставляет меньше методов и использует NorthwindWithSprocs DataSet (вместо Northwind DataSet). Добавьте в класс EmployeesBLLWithSprocs приведенный далее код.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindWithSprocsTableAdapters;
[System.ComponentModel.DataObject]
public class EmployeesBLLWithSprocs
{
    private EmployeesTableAdapter _employeesAdapter = null;
    protected EmployeesTableAdapter Adapter
    {
        get
        {
            if (_employeesAdapter == null)
                _employeesAdapter = new EmployeesTableAdapter();
            return _employeesAdapter;
        }
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Select, true)]
    public NorthwindWithSprocs.EmployeesDataTable GetEmployees()
    {
        return Adapter.GetEmployees();
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Delete, true)]
    public bool DeleteEmployee(int employeeID)
    {
        int rowsAffected = Adapter.Delete(employeeID);
        // Return true if precisely one row was deleted, otherwise false
        return rowsAffected == 1;
    }
}

Свойство EmployeesBLLWithSprocs класса Adapter возвращает экземпляр NorthwindWithSprocs объекта DataSet .EmployeesTableAdapter Используется методами класса и GetEmployeesDeleteEmployee . Метод GetEmployees вызывает соответствующий EmployeesTableAdapterGetEmployees метод , который вызывает хранимую Employees_Select процедуру и заполняет ее результаты в EmployeeDataTable. Метод DeleteEmployee аналогичным образом вызывает EmployeesTableAdapter метод s Delete , который вызывает хранимую Employees_Delete процедуру.

Шаг 5. Работа с данными на уровне представления

Завершив занятие EmployeesBLLWithSprocs , мы готовы к работе с данными сотрудников на странице ASP.NET. Откройте страницу JOINs.aspx в папке AdvancedDAL и перетащите элемент GridView с панели элементов на Designer, установив для его ID свойства значение Employees. Затем из смарт-тега GridView привяжите сетку к новому элементу управления ObjectDataSource с именем EmployeesDataSource.

Настройте ObjectDataSource для использования EmployeesBLLWithSprocs класса и на вкладках SELECT и DELETE убедитесь, что GetEmployees в раскрывающихся списках выбраны методы и DeleteEmployee . Нажмите кнопку Готово, чтобы завершить настройку ObjectDataSource.

Настройка ObjectDataSource для использования класса EmployeesBLLWithSprocs

Рис. 12. Настройка ObjectDataSource для использования EmployeesBLLWithSprocs класса (щелкните для просмотра полноразмерного изображения)

Использование методов GetEmployees и DeleteEmployee в ObjectDataSource

Рис. 13. Использование objectDataSource GetEmployees методов и DeleteEmployee (щелкните для просмотра полноразмерного изображения)

Visual Studio добавит BoundField в GridView для каждого столбца EmployeesDataTable . Удалите все эти Поля BoundField, кроме Title, LastName, FirstNameManagerFirstNameи ManagerLastName и переименуйте HeaderText свойства для последних четырех BoundFields в Last Name, First Name, Manager s First Name и Manager s Last Name, соответственно.

Чтобы разрешить пользователям удалять сотрудников с этой страницы, необходимо выполнить два действия. Во-первых, укажите GridView для предоставления возможностей удаления, установив флажок Включить удаление в смарт-теге. Во-вторых, измените свойство ObjectDataSource со OldValuesParameterFormatString значения, заданного мастером ObjectDataSource (original_{0}), на значение по умолчанию ({0}). После внесения этих изменений декларативная разметка GridView и ObjectDataSource должна выглядеть примерно так:

<asp:GridView ID="Employees" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="EmployeeID" DataSourceID="EmployeesDataSource">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" />
        <asp:BoundField DataField="Title" 
            HeaderText="Title" 
            SortExpression="Title" />
        <asp:BoundField DataField="LastName" 
            HeaderText="Last Name" 
            SortExpression="LastName" />
        <asp:BoundField DataField="FirstName" 
            HeaderText="First Name" 
            SortExpression="FirstName" />
        <asp:BoundField DataField="ManagerFirstName" 
            HeaderText="Manager's First Name" 
            SortExpression="ManagerFirstName" />
        <asp:BoundField DataField="ManagerLastName" 
            HeaderText="Manager's Last Name" 
            SortExpression="ManagerLastName" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="EmployeesDataSource" runat="server" 
    DeleteMethod="DeleteEmployee" OldValuesParameterFormatString="{0}" 
    SelectMethod="GetEmployees" TypeName="EmployeesBLLWithSprocs">
    <DeleteParameters>
        <asp:Parameter Name="employeeID" Type="Int32" />
    </DeleteParameters>
</asp:ObjectDataSource>

Протестируйте страницу, посетив ее в браузере. Как показано на рисунке 14, на странице будет указано имя каждого сотрудника и его руководителя (при условии, что у него есть имя).

Соединение в Employees_Select хранимой процедуре возвращает имя руководителя.

Рис. 14. В JOIN хранимой Employees_Select процедуре возвращается имя руководителя (щелкните для просмотра полноразмерного изображения)

Нажатие кнопки Удалить запускает рабочий процесс удаления, который завершается выполнением хранимой Employees_Delete процедуры. Однако попытка выполнения инструкции в хранимой процедуре завершается DELETE сбоем из-за нарушения ограничения внешнего ключа (см. рис. 15). В частности, каждый сотрудник имеет одну или несколько записей в Orders таблице, что приводит к сбою удаления.

Удаление сотрудника с соответствующими заказами приводит к нарушению ограничения внешнего ключа

Рис. 15. Удаление сотрудника с соответствующими заказами приводит к нарушению ограничения внешнего ключа (щелкните, чтобы просмотреть полноразмерное изображение)

Чтобы разрешить удаление сотрудника, вы можете:

Я оставляю это как упражнение для читателя.

Сводка

При работе с реляционными базами данных запросы обычно извлекают данные из нескольких связанных таблиц. Коррелированные вложенные запросы и JOIN предоставляют два разных метода доступа к данным из связанных таблиц в запросе. В предыдущих руководствах мы чаще всего использовали коррелированные вложенные запросы, так как TableAdapter не может автоматически создать INSERTинструкции , UPDATEи DELETE для запросов, включающих JOIN s. Хотя эти значения можно указать вручную, при использовании нерегламентированных инструкций SQL любые настройки будут перезаписаны после завершения работы мастера настройки TableAdapter.

К счастью, адаптеры TableAdapters, созданные с помощью хранимых процедур, не страдают от той же хрупкости, что и те, которые были созданы с помощью нерегламентированных инструкций SQL. Поэтому при использовании хранимых процедур можно создать TableAdapter, main запрос которого использует JOIN . В этом руководстве мы узнали, как создать такой объект TableAdapter. Мы начали использовать JOINзапрос -less SELECT для запроса main TableAdapter, чтобы соответствующие хранимые процедуры вставки, обновления и удаления создавались автоматически. После завершения начальной настройки TableAdapter мы добавили SelectCommand хранимую JOIN процедуру для использования и повторно запустили мастер настройки TableAdapter для обновления EmployeesDataTable столбцов s.

Повторное выполнение мастера настройки TableAdapter автоматически обновило EmployeesDataTable столбцы, чтобы они отражали поля данных, возвращаемые хранимой Employees_Select процедурой. Кроме того, можно добавить эти столбцы в таблицу DataTable вручную. В следующем руководстве мы рассмотрим добавление столбцов в таблицу DataTable вручную.

Счастливое программирование!

Об авторе

Скотт Митчелл (Scott Mitchell), автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с Веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 2.0 в 24 часа. Его можно связать по адресу mitchell@4GuysFromRolla.com. или через его блог, который можно найти по адресу http://ScottOnWriting.NET.

Отдельная благодарность

Эта серия учебников была проверена многими полезными рецензентами. Ведущие рецензенты этого руководства : Хилтон Гейсеноу, Дэвид Суру и Тереса Мерфи. Хотите ознакомиться с моими предстоящими статьями MSDN? Если да, опустите мне строку в mitchell@4GuysFromRolla.com.