ObjectDataSource
Как уже было сказано, этот класс работает с бизнес-объектами. А что же это такое? Это такие классы, которые инкапсулируют логику работы с данными, нужными в приложении. Класс бизнес-объекта может быть написан на любом языке .NET. Как и все классы, он располагается в папке App_Code. ObjectDataSource работает как связующее звено между бизнес-объектами и элементами управления, отображающими данные. Получается многоуровневая компонентная архитектура. Классы бизнес-объектов могут поменять свое внутреннее представление, и это никак не отразится на страницах, которые их используют. ObjectDataSource работает во многом так же, как SqlDataSource, с той разницей, что он имеет дело не с базой данных, а с классом.
Свойство TypeName класса ObjectDataSource указывает на используемый класс. Класс бизнес-объекта должен поддерживать конструктор и 4 метода (возможно, и больше) — для чтения, редактирования, удаления и добавления данных в источник данных. Элемент управления ObjectDataSource пользуется этими методами.
Например, свойство SelectMethod указывает на метод класса бизнес-объекта, который возвращает данные.
Откуда бизнес-объект берет данные, ему не важно. Некоторые бизнес-объекты работают с базами данных, некоторые — с сессией или текстовыми файлами. Главное, что метод, который он использует для чтения, должен возвращать класс, реализующий интерфейс IEnumerable. UpdateMethod — метод, который обновляет данные. Аналогичную функцию выполняют DeleteMethod и InsertMethod.
Класс бизнес-объекта может поддерживать метод SelectCount, который возвращает общее количество объектов в источнике данных.
ObjectDataSource вызывает этот метод, чтобы реализовать разбиение на страницы.
Рассмотрим это на примере:
public class Continent { ArrayList ContinentArrayList; public Continent() { ContinentArrayList = new ArrayList(); ContinentArrayList.Add("Worldwide"); ContinentArrayList.Add("America"); ContinentArrayList.Add("Africa"); ContinentArrayList. Add("Asia-Pacific");
} public ArrayList List() { return ContinentArrayList; } public int SelectCount() { return ContinentArrayList.Length; } }
Даже такой примитивный класс может использоваться как источник данных для ObjectDataSource, так как ArrayList реализует IEnumerable. Вместо свойств *Command ObjectDataSource использует *Method:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="List" TypeName=" Continent "> </asp:ObjectDataSource> <asp:RadioButtonList ID="RadioButtonList1" runat="server" DataSourceID="ObjectDataSource1"> </asp:RadioButtonList></div>
Достигается тот же эффект, что и раньше, когда данные вставлялись на странице или в классе страницы, но теперь получение данных инкапсулировано в классе Continent. Класс может изменить способ получения данных, не меняя интерфейса. Чаще всего данные все-таки получают из баз данных, XML-файлов или web-сервисов. Классы бизнес-логики могут разрабатывать одни члены команды, а заниматься дизайном страниц — другие. Их можно использовать и в обычных приложениях в Windows Forms.
ObjectDataSource может работать и с типизированными наборами данных, которые можно создать с помощью мастера. Попробуем это сделать на примере таблицы Customers. Создайте в папке App_Code новый файл и в диалоге выбора типа файла выберите dataset. Назовите его Customers. Мастер предложит выбрать строку соединения. Выберите NorthWindConnectionString (если его нет в проекте, создайте, как показано в предыдущей лекции). На следующем шаге мастер предложит выбрать из трех вариантов: использование запросов SQL, создание хранимых процедур или использование готовых процедур. Выберите второе, так как готовых процедур, которые бы обновляли данные, в базе Northwind нет. На следующем шаге нужно будет создать процедуры, это можно сделать с помощью QueryBuilder, очень похожем на дизайнер запросов в MS Access. В списке таблиц выберите Customers, а в таблице несколько полей. Должен получиться запрос
SELECT CustomerID, CompanyName, ContactName, ContactTitle, Country, City FROM Customers
После этого проект желательно скомпилировать.
Мы получили компонент данных. Все готово для связывания его с ObjectDataSource. Перетащите значок нужного класса на форму и с помощью SmartTag запустите еще один мастер. На первом шаге настройте его на CustomersDataAdapters.CustomersDataAdapter. На втором надо выбрать подходящие функции для команд Select, Update, Delete, Insert. Вариантов будет немного — после выбора нажмите Finish. Можно привязывать наш ObjectDataSource к любому подходящему элементу управления, например, GridView:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetData" TypeName="CustomersTableAdapters.CustomersTableAdapter" DeleteMethod="Delete" InsertMethod="Insert" OldValuesParameterFormatString="original_{0}" UpdateMethod="Update"> <DeleteParameters> <asp:Parameter Name="Original_CustomerID" Type="String" /> </DeleteParameters> <UpdateParameters> <asp:Parameter Name="CustomerID" Type="String" /> <asp:Parameter Name="CompanyName" Type="String" /> <asp:Parameter Name="ContactName" Type="String" /> <asp:Parameter Name="ContactTitle" Type="String" /> <asp:Parameter Name="Country" Type="String" /> <asp:Parameter Name="City" Type="String" /> <asp:Parameter Name="Original_CustomerID" Type="String" /> </UpdateParameters> <InsertParameters> <asp:Parameter Name="CustomerID" Type="String" /> <asp:Parameter Name="CompanyName" Type="String" /> <asp:Parameter Name="ContactName" Type="String" /> <asp:Parameter Name="ContactTitle" Type="String" /> <asp:Parameter Name="Country" Type="String" /> <asp:Parameter Name="City" Type="String" /> </InsertParameters> </asp:ObjectDataSource> <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="CustomerID" DataSourceID="1"> <Columns> <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" ShowSelectButton="True" /> <asp:BoundField DataField="CustomerID" HeaderText="CustomerID" ReadOnly="True" SortExpression="CustomerID" /> <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" /> <asp:BoundField DataField="ContactName" HeaderText="ContactName" SortExpression="ContactName" /> <asp:BoundField DataField="ContactTitle" HeaderText="ContactTitle" SortExpression="ContactTitle" /> <asp:BoundField DataField="Country" HeaderText="Country" SortExpression="Country" /> <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" /> </Columns> </asp:GridView>
Класс бизнес- объекта создается неявно. Из файла .xsd можно получить класс типизированного набора данных на языке C# с помощью утилиты xsd.exe.
xsd.exe /dataset /language:CS Customers.xsd.
Из одного класса могут получать данные разные элементы Object DataSource. В приложении Personal Starter Kit определен класс Photo Manager, который работает с базой данных Personal.mdf:
public static Stream GetPhoto(int photoid, PhotoSize size) { using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Personal"].C onnectionString)) { using (SqlCommand command = new SqlCommand("GetPhoto", con- nection)) { command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@PhotoID", photoid)); command.Parameters.Add(new SqlParameter("@Size", (int)size)); bool filter = !(HttpContext.Current.User.IsInRole("Friends") || HttpContext.Current.User.IsInRole("Administrators")); command.Parameters.Add(new SqlParameter("@IsPublic", filter)); connection.Open(); object result = command.ExecuteScalar(); try { return new MemoryStream((byte[])result); } catch { return null; } } }
В этой функции полезно для усвоения получение двоичной информации, например изображений из базы данных.