Поделиться через


начало работы с 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 .

Снимок экрана: окно интернет-Обозреватель, в котором отображается представление

Снимок экрана: окно интернет-Обозреватель с представлениями

Снимок экрана: окно интернет-Обозреватель, в котором отображается представление

Снимок экрана: окно интернет-Обозреватель, в котором отображается представление Найти учащихся по имени с буквой g, введенной в поисковом запросе.

Использование свойства EntityDataSource Where для фильтрации данных

Откройте страницу Students.aspx , созданную в предыдущем руководстве. В текущей конфигурации GridView элемент управления на странице отображает все имена из набора сущностей People . Однако вы хотите отобразить только учащихся, которые можно найти, выбрав сущности Person с датами регистрации, не имеющими значения NULL.

Перейдите в режим конструктораEntityDataSource и выберите элемент управления. В окне Свойства присвойте свойству Where значение it.EnrollmentDate is not null.

Изображение01

В свойстве WhereEntityDataSource элемента управления используется синтаксис 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.

Image05

Запустите страницу. Список учащихся теперь находится в порядке по фамилии.

Image04

Использование параметра элемента управления для задания свойства Where

Как и в случае с другими элементами управления источником данных, в свойство можно передать значения Where параметров. На странице Courses.aspx , созданной в части 2 руководства, этот метод можно использовать для отображения курсов, связанных с отделом, который пользователь выбирает из раскрывающегося списка.

Откройте Courses.aspx и переключитесь в режим конструктора . Добавьте на страницу второй EntityDataSource элемент управления и назовите его CoursesEntityDataSource. Подключите его к SchoolEntities модели и выберите Courses в качестве значения EntitySetName .

В окне Свойства щелкните многоточие в поле свойства Where . (Перед использованием окна Свойства убедитесь, CoursesEntityDataSource что элемент управления по-прежнему выбран.)

Image06

Откроется диалоговое окно Редактор выражений . В этом диалоговом окне выберите Автоматически создавать выражение Where на основе предоставленных параметров и нажмите кнопку Добавить параметр. Назовите параметр DepartmentID, выберите Control в качестве значения источника параметра, а в качестве значения ControlID выберите DepartmentsDropDownList.

Изображение07

Щелкните Показать дополнительные свойства и в окне Свойства диалогового окна Редактор выражений измените свойство на TypeInt32.

Изображение15

Закончив, нажмите кнопку 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.

Image08

Теперь, когда вы закончили работу с конструктором, переключитесь в представление источника и замените ConnectionStringCoursesEntityDataSource свойства и 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 .

Image09

Использование свойства 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.
  • Чтобы упорядочить результаты по дате регистрации, задайте для свойства значение OrderByit.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" (при поиске регистр не учитывается).

Изображение12

Использование оператора Like для фильтрации данных

Вы можете добиться эффекта, аналогичного QueryExtender типам поиска элемента управления StartsWith, Containsи EndsWith , с помощью Like оператора в свойстве EntityDataSourceWhere элемента управления. В этой части учебника вы узнаете, как использовать 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 параметра — "%".

Изображение13

Введите букву "g" в текстовое поле и нажмите кнопку Поиск. Вы увидите список учащихся, у которых есть "g" в имени или фамилии.

Снимок экрана: окно интернет-Обозреватель, в котором отображается представление

Теперь вы отображаете, обновляете, фильтруете, упорядочивали и сгруппировали данные из отдельных таблиц. В следующем руководстве вы приступите к работе со связанными данными (master сценариях с подробными сведениями).