Привязка данных ADO.NET
Старательно сопишь - значит победишь
Компонент управления источником данных ObjectDataSource
Компонент ObjectDataSource находится на вкладке Data панели Toolbox. Он позволяет создавать декларативным (на этапе проектирования) способом связь между элементом отображения и компонентом доступа к данным, который запрашивает и обновляет их. Он является более гибким по сравнению с источником данных SqlDataSource. Но для корректного применения пользовательский класс доступа к данным, которым может быть и разработанный нами класс, должен подчиняться нескольким правилам:
- Пользовательский класс не должен сохранять состояние, поскольку ObjectDataSource создает его экземпляры по необходимости и уничтожает их за собой в конце каждого запроса
- Пользовательский класс должен иметь конструктор по умолчанию (без аргументов)
- Компонент должен быть представлен только одним классом. Если для решения разных частей одной задачи используются несколько классов, то они должны быть упакованы в оболочку одного высокоуровневого класса
- Ни один из основных рабочих методов, используемых для извлечения и обновления записей, не должен быть статическим. Они должны быть только методами экземпляра
- Каждый тип запроса (извлечение, вставка, удаление и обновление) должен быть представлен единственным методом, возвращающим результаты запроса
- Результаты запроса должны размещаться в общедоступных свойствах, которые представляют собой коллекции, массивы или списковые объекты, реализующие интерфейс IEnumerable
- Пользовательский компонент доступа к данным должен размещаться в папке App_Code или быть скомпилированным в сборку и помещен в папку Bin
Выполнение этих правил гарантирует, что привязка данных будет простой и организована без дополнительных усилий с нашей стороны. Отступление от правил требует написания дополнительного кода.
Простое использование ObjectDataSource
Для дальнейшего рассмотрения применим пользовательский компонент доступа к данным, разработанный нами ранее, в простом варианте: конструктор без параметров (конструктор по умолчанию) и метод без параметров.
- На корне Web-дерева создайте папку App_Code командой контекстного меню Add ASP.NET Folder
- На папке Add_Code выполните команду Website/Add Existing Item и скопируйте из папки WebSite8/App_Code все ее содержимое, которое представляет собой описание пользовательского класса EmployeeDB
Вспомним, что ранее мы поместили в базу данных с помощью страницы WebSite8/SaveStoredProcedure.aspx хранимые процедуры.
- Скопируйте в текущее приложение страницу WebSite8/SaveStoredProcedure.aspx, откройте ее и посмотрите, что хранимые процедуры объявляются в ней так
// Объявления хранимых процедур // Вставка записи string sql1 = "CREATE PROCEDURE InsertEmployee " + "@EmployeeID int OUTPUT," + "@FirstName varchar(10)," + "@LastName varchar(20)," + "@TitleOfCourtesy varchar(25) " + "AS " + "INSERT INTO Employees " + "(TitleOfCourtesy, LastName, FirstName, HireDate) " + "VALUES(@TitleOfCourtesy, @LastName, @FirstName, GETDATE()) " + "SET @EmployeeID = @@IDENTITY"; // Удаление записи string sql2 = "CREATE PROCEDURE DeleteEmployee " + "@EmployeeID int " + "AS " + "DELETE FROM Employees WHERE EmployeeID = @EmployeeID"; // Обновление записи string sql3 = "CREATE PROCEDURE UpdateEmployee " + "@EmployeeID int, " + "@FirstName varchar(10)," + "@LastName varchar(20)," + "@TitleOfCourtesy varchar(25) " + "AS " + "UPDATE Employees " + "SET " + "FirstName = @FirstName," + "LastName = @LastName," + "TitleOfCourtesy = @TitleOfCourtesy " + "WHERE EmployeeID = @EmployeeID"; // Выбрать все string sql4 = "CREATE PROCEDURE GetAllEmployees " + "AS " + "SELECT EmployeeID, FirstName, LastName, TitleOfCourtesy " + "FROM Employees"; // Подсчитать число записей string sql5 = "CREATE PROCEDURE CountEmployees " + "AS " + "SELECT COUNT(EmployeeID) " + "FROM Employees"; // Выбрать запись string sql6 = "CREATE PROCEDURE GetEmployee " + "@EmployeeID int " + "AS " + "SELECT EmployeeID, FirstName, LastName, TitleOfCourtesy " + "FROM Employees " + "WHERE EmployeeID = @EmployeeID";Листинг .
В их числе и процедура GetAllEmployees, которую реализует в пользовательском классе EmployeeDB одноименный метод GetAllEmployees(). Эта процедура извлекает из таблицы Employees записи четырех полей в порядке их следования в строке запроса. Если мы укажем помещенному на страницу компоненту ObjectDataSource имя нашего пользовательского класса и имя метода, который реализует в классе нужный SQL-запрос, то ObjectDataSource сам создаст экземпляр этого пользовательского класса и вызовет указанный метод. В результате, объект пользовательского класса будет заполнен данными, которые увидит пользователь через привязанные к компоненту ObjectDataSource элементы отображения.
- Создайте новую страницу с совмещенным кодом и именем ObjectDataSourceSimple.aspx. Назначьте ее стартовой
- Перенесите на страницу ObjectDataSourceSimple.aspx из панели Toolbox следующие компоненты
-
Выполните простые настройки свойств компонентов, чтобы окончательный код страницы стал таким
<%@ Page Language="C#" %> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetAllEmployees" TypeName="EmployeeDB" /> <asp:ListBox ID="ListBox1" runat="server" DataSourceID="ObjectDataSource1" DataTextField="LastName" /> <asp:GridView ID="GridView1" runat="server" DataSourceID="ObjectDataSource1" /> </div> </form> </body> </html>
- Исполните страницу ObjectDataSourceSimple.aspx, чтобы получить следующий результат
Исключительно простой получилась привязка данных к элементам отображения через компонент ObjectDataSource. Никакого кода не пришлось писать. Прямо - работа для дизайнеров или кухарок! Но пользовательский-то класс EmployeeDB мы ранее с вами создали. Его просто здесь не видно - он работает за кулисами и вызывается по ссылке, указанной в свойстве TypeName компонента ObjectDataSource. Элементы отображения, в свою очередь, получают свою порцию данных через ссылку на заполненный ObjectDataSource, указанную в свойстве DataSourceID.