Пример использования EntityDataSource
Обновлен: Ноябрь 2007
В приведенном в этом разделе примере демонстрируется использование элемента управления EntityDataSource ADO.NET для реализации сценария привязки данных. Рассматриваемое приложение отображает элементы таблицы SalesOrderDetail, связанные с заголовком SalesOrderHeader, идентифицируемым ключом удостоверения таблицы SalesOrderHeader. Используемая в приложении модель данных основана на учебной базе данных AdventureWorks, поставляемой вместе с SQL Server 2005.
На следующем снимке экрана показана работа пользователя с приложением. В списке с левой стороны страницы содержатся ключи удостоверений элементов таблицы SalesOrderHeader. На снимке пользователь щелкнул заголовок (элемент таблицы SalesOrderHeader) номер 43666. Связанные с ним элементы таблицы SalesOrderDetail отображаются в правой части страницы с помощью элемента управления Gridview.
Реализация примера
Реализация этого примера включает следующие этапы.
Создание веб-приложения ASP.NET.
Добавление сущностной модели данных (EDM) ADO.NET, основанной на базе данных AdventureWorks.
Добавление списка для отображения ключей таблицы SalesOrderHeader.
Добавление элемента управления GridView для отображения связанных элементов таблицы SalesOrderDetail.
Добавление и настройка двух элементов управления EntityDataSource для поставки данных списку и элементу управления GridView.
Добавление обработчика событий для события "выбор в списке-изменение индекса".
Создание веб-приложения ASP.NET
В Visual Studio из меню Файл создайте новое приложение ASP.NET. Назовите проект GetOrders EDSC. Откроется разметка страницы Default.aspx с пустыми HTML-элементами form иdiv.
Введите заголовок страницы между тегами <title> разметки.
Добавление сущностной модели данных (EDM) ADO.NET
Данные, которые будут использоваться в этом приложении, представляют собой реализацию сущностной модели данных (EDM), основанную на таблицах учебной базы данных AdventureWorks, поставляемой вместе с SQL Server 2005.
Объявлено пять сущностей:
Address
Contact
Product
SalesOrderDetail
SalesOrderHeader
Экземпляры этих типов логически содержатся в наборах сущностей с теми же именами в объектной модели, построенной по концептуальной схеме.
Объявлено три ассоциации и набора ассоциаций. Имена всех перечисленных ниже ассоциаций начинаются с префикса "FK_". Этот префикс отражает связь по внешнему ключу между таблицами данных AdventureWorks.
FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID
FK_SalesOrderHeader_Address_ShipToAddressID
FK_SalesOrderHeader_Contact_ContactID
Чтобы создать модель данных Sales из AdventureWorks:
Щелкните правой кнопкой проект GetOrders EDSC в Обозревателе решений.
Выберите пункт Добавить и затем Новый элемент.
Выберите шаблон ADO.NET Entity Data Model и дайте новой модели данных имя AdvWksSales.edmx.
В мастере модели EDM выберите пункт Создать из базы данных и нажмите кнопку Далее.
Создайте подключение к базе данных AdventureWorks и нажмите кнопку Далее.
В диалоговом окне Выбор объектов базы данных выберите Address, Contact, Product, SalesOrderDetail и SalesOrderHeading. Нажмите кнопку Готово.
В конструкторе откроется файл AdvWksSales.edmx, содержащий сущности и ассоциации модели данных. Обратите внимание на ассоциацию "один-ко-многим" между сущностью SalesOrderHeader и сущностью SalesOrderDetail. Эти два типа данных и ассоциация между ними будут использоваться в приложении-примере. Выполните построение проекта, чтобы создать модель данных.
Добавление элементов управления для отображения данных
Для отображения ключей сущностей SalesOrderHeader и связанных элементов сущности SalesOrderDetail необходимо два элемента управления данными.
Чтобы добавить на страницу элементы управления:
Откройте страницу Default.aspx в представлении конструирования Visual Studio и перетащите границу элемента div вниз, чтобы у вас было достаточно места для добавления элементов управления.
Добавьте надпись со следующим текстом: Select SalesOrderHeaderID.
Под надписью добавьте список. Можно оставить идентификатор по умолчанию — ListBox1. Задайте размеры и положение списка в соответствии с разметкой страницы, приведенной в конце данного раздела.
Добавьте на страницу элемент управления GridView и задайте его положение в соответствии с разметкой страницы, приведенной в конце данного раздела. Можно оставить идентификатор по умолчанию — GridView1.
Над элементом управления GridView добавьте надпись со следующим текстом: SalesOrderHeader ID.
Добавьте еще одну надпись над элементом управления GridView. Эта надпись будет использоваться в параметре свойства CommandText. Присвойте ей идентификатор, соответствующий ее назначению, например labelHeaderIDFromList. Измените текст надписи на пустую строку.
Добавление и настройка элементов управления EntityDataSource
Чтобы добавить элементы управления EntityDataSource:
Добавьте на страницу элемент управления EntityDataSource. Дайте этому элементу управления EntityDataSource имя EntDataSrc_OrderID. Этот элемент управления будет привязан к списку ListBox1 для отображения ключей SalesOrderHeader.
Добавьте на страницу еще один элемент управления EntityDataSource. Дайте этому элементу управления EntityDataSource имя EntDataSrc_OrderDetails. Этот элемент управления будет привязан к элементу управления Gridview1 для отображения сущностей SalesOrderDetail, связанных с ключом удостоверения SalesOrderHeader, выбранным пользователем в списке ListBox1.
Примечание. |
---|
Если с момента добавления сущностной модели данных (EDM) для AdvWksSalesModel не выполнялось построение проекта, выполните построение объекта сейчас; в противном случае на следующих шагах проект не будет функционировать описанным образом. При построении EDM-проекта артефакты метаданных EDM помещаются расположение, определяемое строкой подключения в файле WebConfig. |
Чтобы настроить привязку данных списка ListBox1 к элементу управления EntDataSrc_OrderID:
Щелкните символ > на элементе управления EntityDataSource.
Выберите пункт Настроить источник данных.
В диалоговом окне Настройте контекст объекта выберите AdventureWorksEntities в раскрывающемся списке Именованное подключение. Это идентифицирует строку подключения из файла WebConfig.
В раскрывающемся списке DefaultContainerName выберите AdventureWorksEntities. Это имя контейнера EntityContainer, который модель данных использует в своей схеме разработки. Нажмите кнопку Далее.
В диалоговом окне Настройте выбор данных выберите SalesOrderHeader в раскрывающемся списке EntitySetName. Этот тип не является частью иерархии наследования, поэтому поле EntityTypeFilter можно оставить пустым.
В области Оператор SELECT установите флажок SalesOrderID. Нажмите кнопку Готово.
Щелкните символ > на списке ListBox1 и выберите пункт Выбрать источник данных.
В диалоговом окне Выбор источника данных выберите EntDataSrc_OrderID в раскрывающемся списке Выберите источник данных. В следующих двух раскрывающихся списках выберите SalesOrderID.
Нажмите кнопку ОК.
На данном этапе полезно будет запустить приложение. В списке будут отображаться все ключи удостоверений сущностей SalesOrderHeader в источнике данных. Эта информация будет полезна после реализации остальной части приложения, когда пользователь сможет выбрать один ключ и отобразить все сущности SalesOrderDetail, связанные с сущностью SalesOrderHeader, в элементе управления Gridview1 в правой части страницы.
Настройка EntityDataSource с элементом управления GridView
Чтобы привязать связанные заказы к элементу управления Gridview1:
Выберите элемент управления EntityDataSource с именем EntDataSrc_OrderDetails в области конструирования страницы Default.aspx.
Щелкните символ > на элементе управления EntityDataSource.
Выберите пункт Настроить источник данных.
В диалоговом окне Настройте контекст объекта выберите AdventureWorksEntities в раскрывающемся списке Именованное подключение.
В раскрывающемся списке DefaultContainerName выберите AdventureWorksEntities.
Нажмите кнопку Далее.
В диалоговом окне Настройте выбор данных выберите SalesOrderDetail в раскрывающемся списке EntitySetName. Этот тип не является частью иерархии наследования, поэтому поле EntityTypeFilter можно оставить пустым.
В области Оператор SELECT установите флажки SalesOrderDetailID, OrderQty, ProductID, UnitPrice и ModifiedDate.
Нажмите кнопку Готово.
Щелкните правой кнопкой мыши элемент управления EntityDataSource и выберите пункт Свойства.
В списке Свойства выберите Where и щелкните многоточие справа в текстовом поле.
В диалоговом окне Редактор выражения введите следующий текст в текстовой области Выражение Where: it.[SalesOrderID] = @parSalesOrderID.
Нажмите кнопку Добавить параметр под списком Параметры. Дайте новому параметру имя parSalesOrderID. Этот параметр будет получен из текста надписи, задаваемого при выборе пользователем ключа удостоверения в списке SalesOrderHeader. Это указывается в раскрывающемся списке Источник параметров.
Выберите Элемент управления.
В раскрывающемся списке ControlID выберите labelHeaderIDFromList.
Нажмите кнопку ОК.
Обработчик событий для события "выбор в списке-изменения индекса "
Последний этап в реализации данного приложения — соединить выбор пользователем ключа удостоверения для сущности SalesOrderHeader с запросом, который будет возвращать свойства всех сущностей SalesOrderDetail, связанных с выбранной сущностью SalesOrderHeader.
На предыдущем этапе запрос был настроен на возвращение свойств SalesOrderDetailID, OrderQty, ProductID, UnitPrice и ModifiedDate. Элемент управления EntityDataSource настроен на получение параметра от элемента управления labelHeaderIDFromList на веб-странице и передачу его предложению Where запроса, который идентифицирует сущность SalesOrderHeader, связанную с сущностями SalesOrderDetail, свойства которых будут отображены. Теперь необходимо добавить код, который будет задавать свойство текста элемента управления labelHeaderIDFromList равным выбранному пользователем ключу удостоверения сущности SalesOrderHeader.
Чтобы создать обработчик события SelectedIndexChanged списка ListBox1:
Выберите список ListBox1 в области конструирования веб-страницы.
Щелкните правой кнопкой мыши список ListBox1 и выберите пункт Свойства.
В списке Свойства щелкните значок событий.
Дважды щелкните событие SelectedIndexChanged. Откроется страница с выделенным кодом ASP.NET с именем Default.aspx.cs или Default.aspx.vb, содержащая блок кода для обработчика событий.
Создайте обработчик событий, показанный в блоке кода после шага 6. Код в обработчике устанавливает значение элемента управления labelHeaderIDFromList равным значению, выбранному пользователем в элементе управления ListBox1. Затем он присваивает свойство DataSource элемента управления GridView1 элементу управления EntDataSrcOrder. Наконец, он вызывает метод DataBind в элементе управления EntDataSrc_OrderDetails. Этот элемент управления был настроен на запрос данных по ключу удостоверения, полученному из элемента управления labelHeaderIDFromList.
Установите значение свойства AutoPostBack элемента управления ListBox1 равным true, чтобы сервер мог считывать выбранные данные сразу же после их выбора.
protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
labelHeaderIDFromList.Text = ListBox1.SelectedValue;
GridView1.DataSource = EntDataSrc_OrderDetails;
GridView1.DataBind();
}
При активации события SelectedIndexChanged запускается предопределенный запрос с параметризованным предложением Where. Свойства, отображаемые в элементе управления GridView1 — это свойства сущностей SalesOrderDetail, связанные с сущностью SalesOrderHeader, выбранной в списке ListBox1.
Разметка страницы со всеми элементами управления
Следующая разметка страницы содержит все элементы управления и свойства, инициализированные в приложении, предназначенном для отображения сущностей SalesOrderDetail, связанных с сущностью SalesOrderHeader. Предложение Where содержит параметр, содержащий внешний ключ сущности SalesOrderHeader, связанный с сущностями SalesOrderDetail.
<body>
<form id="form1" runat="server">
<div style="height: 450px">
<br />
<asp:ListBox ID="ListBox1" runat="server"
Height="275px"
Width="100px"
style="position:absolute; left:50px; top:80px"
DataSourceID="EntDataSrc_OrderID" DataTextField="SalesOrderID"
DataValueField="SalesOrderID" AutoPostBack="True"
onselectedindexchanged="ListBox1_SelectedIndexChanged" >
</asp:ListBox>
<asp:GridView ID="GridView1" runat="server"
style="position:absolute; left:200px; top:75px">
</asp:GridView>
<asp:Label ID="Label1" runat="server"
Text="Select SalesOrderHeaderID"></asp:Label>
<asp:Label ID="Label2" runat="server" Text="SalesOrderHeaderID:"></asp:Label>
<asp:Label ID="labelHeaderIDFromList" runat="server"></asp:Label>
</div>
<asp:EntityDataSource ID="EntDataSrc_OrderID" runat="server"
ConnectionString="name=AdventureWorksEntities"
DefaultContainerName="AdventureWorksEntities"
EntitySetName="SalesOrderHeader">
</asp:EntityDataSource>
<asp:EntityDataSource ID="EntDataSrc_OrderDetails" runat="server"
ConnectionString="name=AdventureWorksEntities"
DefaultContainerName="AdventureWorksEntities"
EntitySetName="SalesOrderDetail"
Select="it.[SalesOrderDetailID], it.[OrderQty],
it.[ProductID], it.[UnitPrice], it.[ModifiedDate]"
Where="it.[SalesOrderID] = @parSalesOrderID">
<WhereParameters>
<asp:ControlParameter Name="parSalesOrderID" ControlID="labelHeaderIDFromList" Type="Int32"/>
</WhereParameters>
</asp:EntityDataSource>
</form>
</body>
Реализация с текстом команды
Разметка в предыдущем разделе соответствует реализации, в которой для отображения связанных с сущностью SalesOrderHeader сущностей SalesOrderDetail используется предложение Where. Аналогичные результаты можно получить путем использования свойства CommandText с запросом Entity SQL. Параметр в этом случае используется в сочетании с запросом, содержащем левостороннюю корреляцию. Левосторонняя корреляция находит свойства сущностей SalesOrderHeader и SalesOrderDetail.
<body>
<form id="form1" runat="server">
<div style="height: 430px; width: 805px">
Search Sales Orders <br />
Select Order ID:
<br />
<asp:Label ID="LabelHeaderID"
runat="server" Text="SalesOrderHeaderID:"
style="position:absolute; left:200px; top:40px"></asp:Label>
<asp:Label ID="LabelHeaderIDFromList" runat="server" Text=""
style="position:absolute; left:375px; top:40px"></asp:Label>
<br />
<asp:ListBox ID="ListBox1" runat="server"
DataSourceID="EntDatSrc_OrderID"
DataTextField="SalesOrderID"
DataValueField="SalesOrderID" Height="285px"
Width="100px" style="position:absolute;
left:50px; top:80px"
AutoPostBack="True"
onselectedindexchanged="ListBox1_SelectedIndexChanged">
</asp:ListBox>
<asp:GridView ID="GridView1" runat="server"
style="position:absolute; left:200px; top:80px"
AllowPaging="false">
</asp:GridView>
<br />
</div>
<asp:EntityDataSource ID="EntDatSrc_OrderID" runat="server"
DefaultContainerName="AdventureWorksEntities"
EntitySetName="SalesOrderHeader"
Select="it.[SalesOrderID]"
ConnectionString="name=AdventureWorksEntities">
</asp:EntityDataSource>
<asp:EntityDataSource ID="EntDatSrcOrderDetails" runat="server"
DefaultContainerName="AdventureWorksEntities"
CommandText="SELECT soh.SalesOrderID, sod.SalesOrderDetailID,
sod.OrderQty, sod.ProductID, sod.UnitPrice, sod.ModifiedDate
FROM AdventureWorksEntities.SalesOrderHeader
AS soh, soh.SalesOrderDetail AS sod
WHERE soh.SalesOrderID = @parSalesOrderID"
ConnectionString="name=AdventureWorksEntities" >
<CommandParameters>
<asp:ControlParameter Name="parSalesOrderID"
ControlID="LabelHeaderIDFromList" Type="Int32"/>
</CommandParameters>
</asp:EntityDataSource>
</form>
</body>