начало работы с entity Framework 4.0 Database First и ASP.NET 4 веб-формы— часть 3
Пример веб-приложения Contoso University демонстрирует создание ASP.NET Web Forms приложений с помощью Entity Framework 4.0 и Visual Studio 2010. Сведения о серии учебников см. в первом руководстве серии
Фильтрация, упорядочение и группирование данных
В предыдущем руководстве EntityDataSource
вы использовали элемент управления для отображения и изменения данных. В этом руководстве вы будете фильтровать, упорядочить и группировать данные. Если это сделать, задав свойства EntityDataSource
элемента управления, синтаксис отличается от синтаксиса других элементов управления источником данных. Однако, как вы увидите, вы можете использовать элемент управления, QueryExtender
чтобы свести к минимуму эти различия.
Вы измените страницу Students.aspx , чтобы отфильтровать учащихся, сортировать по имени и выполнять поиск по имени. Вы также измените страницу Courses.aspx , чтобы отобразить курсы для выбранного отдела и выполнить поиск курсов по имени. Наконец, вы добавите статистику учащихся на страницу About.aspx .
Использование свойства EntityDataSource Where для фильтрации данных
Откройте страницу Students.aspx , созданную в предыдущем руководстве. В текущей конфигурации GridView
элемент управления на странице отображает все имена из набора сущностей People
. Однако вы хотите отобразить только учащихся, которые можно найти, выбрав сущности Person
с датами регистрации, не имеющими значения NULL.
Перейдите в режим конструктораEntityDataSource
и выберите элемент управления. В окне Свойства присвойте свойству Where
значение it.EnrollmentDate is not null
.
В свойстве Where
EntityDataSource
элемента управления используется синтаксис Entity SQL. Entity SQL похож на Transact-SQL, но настраивается для использования с сущностями, а не с объектами базы данных. В выражении it.EnrollmentDate is not null
слово it
представляет ссылку на сущность, возвращенную запросом. Таким образом, it.EnrollmentDate
ссылается на EnrollmentDate
свойство сущности Person
, возвращаемой элементом EntityDataSource
управления.
Запустите страницу. В списке учащихся теперь содержатся только учащиеся. (Строки, в которых нет даты регистрации, не отображаются.)
Использование свойства EntityDataSource "OrderBy" для заказа данных
Вы также хотите, чтобы этот список был в порядке имен при первом отображении. Если страница Students.aspx по-прежнему открыта в режиме конструктора , а элемент управления по-прежнему EntityDataSource
выбран, в окне Свойства задайте для свойства OrderBy значение it.LastName
.
Запустите страницу. Список учащихся теперь находится в порядке по фамилии.
Использование параметра элемента управления для задания свойства Where
Как и в случае с другими элементами управления источником данных, в свойство можно передать значения Where
параметров. На странице Courses.aspx , созданной в части 2 руководства, этот метод можно использовать для отображения курсов, связанных с отделом, который пользователь выбирает из раскрывающегося списка.
Откройте Courses.aspx и переключитесь в режим конструктора . Добавьте на страницу второй EntityDataSource
элемент управления и назовите его CoursesEntityDataSource
. Подключите его к SchoolEntities
модели и выберите Courses
в качестве значения EntitySetName .
В окне Свойства щелкните многоточие в поле свойства Where . (Перед использованием окна Свойства убедитесь, CoursesEntityDataSource
что элемент управления по-прежнему выбран.)
Откроется диалоговое окно Редактор выражений . В этом диалоговом окне выберите Автоматически создавать выражение Where на основе предоставленных параметров и нажмите кнопку Добавить параметр. Назовите параметр DepartmentID
, выберите Control в качестве значения источника параметра, а в качестве значения ControlID выберите DepartmentsDropDownList.
Щелкните Показать дополнительные свойства и в окне Свойства диалогового окна Редактор выражений измените свойство на Type
Int32
.
Закончив, нажмите кнопку OK.
Под раскрывающимся списком добавьте элемент GridView
управления на страницу и назовите его CoursesGridView
. Подключите его к элементу CoursesEntityDataSource
управления источником данных, щелкните Обновить схему, щелкните Изменить столбцы и удалите DepartmentID
столбец. Разметка GridView
элемента управления похожа на следующий пример.
<asp:GridView ID="CoursesGridView" runat="server" AutoGenerateColumns="False"
DataKeyNames="CourseID" DataSourceID="CoursesEntityDataSource">
<Columns>
<asp:BoundField DataField="CourseID" HeaderText="ID" ReadOnly="True"
SortExpression="CourseID" />
<asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
<asp:BoundField DataField="Credits" HeaderText="Credits"
SortExpression="Credits" />
</Columns>
</asp:GridView>
Когда пользователь изменяет выбранный отдел в раскрывающемся списке, вы хотите, чтобы список связанных курсов изменился автоматически. Чтобы это произошло, выберите раскрывающийся список и в окне Свойства задайте для AutoPostBack
свойства значение True
.
Теперь, когда вы закончили работу с конструктором, переключитесь в представление источника и замените ConnectionString
CoursesEntityDataSource
свойства и DefaultContainer
имени элемента управления атрибутом ContextTypeName="ContosoUniversity.DAL.SchoolEntities"
. Когда все будет готово, разметка для элемента управления будет выглядеть, как в следующем примере.
<asp:EntityDataSource ID="CoursesEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="false"
EntitySetName="Courses"
AutoGenerateWhereClause="true" Where="">
<WhereParameters>
<asp:ControlParameter ControlID="DepartmentsDropDownList" Type="Int32"
Name="DepartmentID" PropertyName="SelectedValue" />
</WhereParameters>
</asp:EntityDataSource>
Запустите страницу и используйте раскрывающийся список для выбора различных отделов. В элементе управления отображаются только курсы, предлагаемые выбранным отделом GridView
.
Использование свойства EntityDataSource "GroupBy" для группировки данных
Предположим, что Университет Contoso хочет разместить статистику учащихся на странице О программе. В частности, требуется отобразить разбивку числа учащихся по дате их зачисления.
Откройте Файл About.aspx и в представлении "Источник " замените существующее содержимое BodyContent
элемента управления на "Статистика тела учащихся" между h2
тегами:
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>Student Body Statistics</h2>
</asp:Content>
После заголовка добавьте элемент EntityDataSource
управления и назовите его StudentStatisticsEntityDataSource
. Подключите его к SchoolEntities
, выберите People
набор сущностей и оставьте поле Выбрать в мастере без изменений. Задайте следующие свойства в окне Свойства :
- Чтобы отфильтровать только учащихся, присвойте свойству
Where
значениеit.EnrollmentDate is not null
. - Чтобы сгруппировать результаты по дате регистрации, присвойте свойству
GroupBy
значениеit.EnrollmentDate
. - Чтобы выбрать дату регистрации и количество учащихся, задайте для
Select
свойства значениеit.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents
. - Чтобы упорядочить результаты по дате регистрации, задайте для свойства значение
OrderBy
it.EnrollmentDate
.
В представлении источника замените ConnectionString
свойства ContextTypeName
и DefaultContainer
name на свойство . Разметка EntityDataSource
элемента управления теперь похожа на следующий пример.
<asp:EntityDataSource ID="StudentStatisticsEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="People"
Select="it.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents"
OrderBy="it.EnrollmentDate" GroupBy="it.EnrollmentDate"
Where="it.EnrollmentDate is not null" >
</asp:EntityDataSource>
Синтаксис Select
свойств , GroupBy
и Where
похож на Transact-SQL, за it
исключением ключевое слово, задающей текущую сущность.
Добавьте следующую разметку, чтобы создать GridView
элемент управления для отображения данных.
<asp:GridView ID="StudentStatisticsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="StudentStatisticsEntityDataSource">
<Columns>
<asp:BoundField DataField="EnrollmentDate" DataFormatString="{0:d}"
HeaderText="Date of Enrollment"
ReadOnly="True" SortExpression="EnrollmentDate" />
<asp:BoundField DataField="NumberOfStudents" HeaderText="Students"
ReadOnly="True" SortExpression="NumberOfStudents" />
</Columns>
</asp:GridView>
Запустите страницу, чтобы просмотреть список, показывающий количество учащихся по дате регистрации.
Использование элемента управления QueryExtender для фильтрации и упорядочения
Элемент QueryExtender
управления позволяет указать фильтрацию и сортировку в разметке. Синтаксис не зависит от используемой системы управления базами данных (СУБД). Он также обычно не зависит от Entity Framework, за исключением того, что синтаксис, используемый для свойств навигации, уникален для Entity Framework.
В этой части учебника вы будете использовать QueryExtender
элемент управления для фильтрации и упорядочивания данных, а одно из полей order-by будет свойством навигации.
(Если вы предпочитаете использовать код вместо разметки для расширения запросов, которые автоматически создаются элементом EntityDataSource
управления, это можно сделать, обрабатывая QueryCreated
событие . Таким образом QueryExtender
элемент управления также расширяет EntityDataSource
запросы элементов управления.)
Откройте страницу Courses.aspx и под добавленной ранее разметкой вставьте следующую разметку, чтобы создать заголовок, текстовое поле для ввода строк поиска, кнопку поиска и элемент управления, привязанный EntityDataSource
к набору Courses
сущностей.
<h2>Courses by Name</h2>
Enter a course name
<asp:TextBox ID="SearchTextBox" runat="server"></asp:TextBox>
<asp:Button ID="SearchButton" runat="server" Text="Search" />
<br /><br />
<asp:EntityDataSource ID="SearchEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="Courses"
Include="Department" >
</asp:EntityDataSource>
Обратите внимание, что свойству EntityDataSource
элемента управления Include
присвоено значение Department
. В базе данных таблица не содержит имя отдела; Course
она содержит DepartmentID
столбец внешнего ключа. Если бы вы запрашивали базу данных напрямую, чтобы получить название отдела вместе с данными курса, необходимо объединить Course
таблицы и Department
. Задав Include
для свойства значение Department
, вы указываете, что Entity Framework должна выполнять работу по получению связанной Department
сущности при получении сущности Course
. Затем Department
сущность сохраняется в свойстве навигации Department
сущности Course
. (По умолчанию класс, созданный конструктором моделей данных, SchoolEntities
извлекает связанные данные, когда это необходимо, и вы привязали к нему элемент управления источником данных, поэтому задавать Include
свойство не нужно. Однако задание повышает производительность страницы, так как в противном случае Entity Framework будет выполнять отдельные вызовы к базе данных для получения данных для Course
сущностей и связанных Department
сущностей.)
EntityDataSource
После создания элемента управления вставьте следующую разметку, чтобы создать элемент управления, привязанный QueryExtender
к элементу EntityDataSource
управления.
<asp:QueryExtender ID="SearchQueryExtender" runat="server"
TargetControlID="SearchEntityDataSource" >
<asp:SearchExpression SearchType="StartsWith" DataFields="Title">
<asp:ControlParameter ControlID="SearchTextBox" />
</asp:SearchExpression>
<asp:OrderByExpression DataField="Department.Name" Direction="Ascending">
<asp:ThenBy DataField="Title" Direction="Ascending" />
</asp:OrderByExpression>
</asp:QueryExtender>
Элемент SearchExpression
указывает, что вы хотите выбрать курсы, названия которых соответствуют значению, указанному в текстовом поле. Будет сравниваться только столько символов, сколько введено в текстовом поле, так как SearchType
свойство указывает StartsWith
.
Элемент OrderByExpression
указывает, что результирующий набор будет упорядочен по названию курса в названии отдела. Обратите внимание на то, как указано название отдела: Department.Name
. Так как связь между сущностью Course
и сущностью Department
является "один к одному", свойство навигации Department
содержит Department
сущность. (Если бы это была связь "один ко многим", свойство содержало бы коллекцию.) Чтобы получить название отдела, необходимо указать Name
свойство сущности Department
.
Наконец, добавьте GridView
элемент управления для отображения списка курсов:
<asp:GridView ID="SearchGridView" runat="server" AutoGenerateColumns="False"
DataKeyNames="CourseID" DataSourceID="SearchEntityDataSource" AllowPaging="true">
<Columns>
<asp:TemplateField HeaderText="Department">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("Department.Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="CourseID" HeaderText="ID"/>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Credits" HeaderText="Credits" />
</Columns>
</asp:GridView>
Первый столбец — это поле шаблона, в котором отображается название отдела. Выражение привязки данных указывает Department.Name
, как это было показано в элементе QueryExtender
управления .
Запустите страницу. На начальном экране отображается список всех курсов по порядку по отделам, а затем по названию курса.
Введите "m" и нажмите кнопку Поиск , чтобы просмотреть все курсы, названия которых начинаются с "m" (при поиске регистр не учитывается).
Использование оператора Like для фильтрации данных
Вы можете добиться эффекта, аналогичного QueryExtender
типам поиска элемента управления StartsWith
, Contains
и EndsWith
, с помощью Like
оператора в свойстве EntityDataSource
Where
элемента управления. В этой части учебника вы узнаете, как использовать Like
оператор для поиска учащегося по имени.
Откройте Students.aspx в представлении исходного кода . GridView
После элемента управления добавьте следующую разметку:
<h2>Find Students by Name</h2>
Enter any part of the name
<asp:TextBox ID="SearchTextBox" runat="server" AutoPostBack="true"></asp:TextBox>
<asp:Button ID="SearchButton" runat="server" Text="Search" />
<br />
<br />
<asp:EntityDataSource ID="SearchEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="People"
Where="it.EnrollmentDate is not null and (it.FirstMidName Like '%' + @StudentName + '%' or it.LastName Like '%' + @StudentName + '%')" >
<WhereParameters>
<asp:ControlParameter ControlID="SearchTextBox" Name="StudentName" PropertyName="Text"
Type="String" DefaultValue="%"/>
</WhereParameters>
</asp:EntityDataSource>
<asp:GridView ID="SearchGridView" runat="server" AutoGenerateColumns="False" DataKeyNames="PersonID"
DataSourceID="SearchEntityDataSource" AllowPaging="true">
<Columns>
<asp:TemplateField HeaderText="Name" SortExpression="LastName, FirstMidName">
<ItemTemplate>
<asp:Label ID="LastNameFoundLabel" runat="server" Text='<%# Eval("LastName") %>'></asp:Label>,
<asp:Label ID="FirstNameFoundLabel" runat="server" Text='<%# Eval("FirstMidName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Enrollment Date" SortExpression="EnrollmentDate">
<ItemTemplate>
<asp:Label ID="EnrollmentDateFoundLabel" runat="server" Text='<%# Eval("EnrollmentDate", "{0:d}") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Эта разметка похожа на то, что вы видели ранее, за Where
исключением значения свойства . Вторая часть Where
выражения определяет поиск подстроки (LIKE %FirstMidName% or LIKE %LastName%
), которая выполняет поиск по имени и фамилии по введенному в текстовом поле.
Запустите страницу. Изначально отображаются все учащиеся, так как значение по умолчанию для StudentName
параметра — "%".
Введите букву "g" в текстовое поле и нажмите кнопку Поиск. Вы увидите список учащихся, у которых есть "g" в имени или фамилии.
Теперь вы отображаете, обновляете, фильтруете, упорядочивали и сгруппировали данные из отдельных таблиц. В следующем руководстве вы приступите к работе со связанными данными (master сценариях с подробными сведениями).