Начало работы с Entity Framework 4,0 Database First и веб-форм ASP.NET 4. часть 3

от Tom Dykstra)

Пример веб-приложения университета Contoso демонстрирует создание приложений ASP.NET Web Forms с помощью Entity Framework 4,0 и Visual Studio 2010. Сведения о серии руководств см. в первом учебнике серии .

Фильтрация, упорядочение и группирование данных

В предыдущем учебнике для просмотра и изменения данных использовался элемент управления EntityDataSource. В этом учебнике вы будете фильтровать, упорядочивать и группировать данные. При этом при установке свойств элемента управления EntityDataSource синтаксис отличается от других элементов управления источниками данных. Но вы увидите, что для сворачивания этих различий можно использовать элемент управления QueryExtender.

Вы измените страницу students. aspx , чтобы отфильтровать учащихся, сортировать по имени и искать по имени. Вы также измените страницу Courses. aspx , чтобы отобразить курсы для выбранного отдела и найти курсы по имени. Наконец, вы добавите статистику для учащихся на страницу About. aspx .

Image02

Image11

Image10

Image14

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

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

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

image01

Синтаксис, используемый в свойстве Where элемента управления EntityDataSource, Entity SQL. Entity SQL похож на Transact-SQL, но он настроен для использования с сущностями, а не с объектами базы данных. В it.EnrollmentDate is not nullе выражения слово it представляет ссылку на сущность, возвращенную запросом. Таким образом, it.EnrollmentDate ссылается на свойство EnrollmentDate сущности Person, которую возвращает элемент управления EntityDataSource.

Запустите страницу. Список учащихся теперь содержит только учащихся. (Нет строк, которые отображаются там, где нет даты регистрации.)

Image02

Использование свойства 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, выберите элемент управления в качестве значения источника параметра и выберите департментсдропдовнлист в качестве значения ControlID .

Image07

Нажмите кнопку " отобразить дополнительные свойства" и в окне " свойства " диалогового окна редактор выражений измените значение свойства Type на Int32.

Image15

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

После завершения работы с конструктором переключитесь в представление исходного кода и замените свойства ConnectionString и DefaultContainer имени элемента управления CoursesEntityDataSource атрибутом 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 некоторую статистику на основе текста учащихся. В частности, он хочет показать подразделение количества учащихся на дату их регистрации.

Откройте 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 и DefaultContainer именем свойством ContextTypeName. Разметка элемента управления 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>

Запустите страницу, чтобы просмотреть список, отображающий число учащихся по дате регистрации.

Image10

Использование элемента управления элемента для фильтрации и упорядочения

Элемент управления QueryExtender предоставляет способ задания фильтрации и сортировки в разметке. Синтаксис не зависит от используемой системы управления базами данных (СУБД). Обычно он не зависит от Entity Framework, за исключением того, что синтаксис, используемый для свойств навигации, уникален для Entity Framework.

В этой части учебника будет использоваться элемент управления QueryExtender для фильтрации и упорядочения данных, а одно из полей ORDER-BY — это свойство навигации.

(Если вы предпочитаете использовать код вместо разметки для расширения запросов, автоматически создаваемых элементом управления EntityDataSource, это можно сделать, обрабатывая событие QueryCreated. Именно так QueryExtender элемент управления расширяет запросы EntityDataSource Control.)

Откройте страницу 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>

Обратите внимание, что свойство Include EntityDataSource элемента управления имеет значение 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>

Первый столбец — это поле шаблона, в котором отображается название отдела. Выражение DataBinding задает Department.Name, как показано в элементе управления QueryExtender.

Запустите страницу. В начальном отображении отображается список всех курсов, упорядоченных по отделам, а затем по названию курса.

Image11

Введите "m" и нажмите кнопку " Поиск ", чтобы просмотреть все курсы, названия которых начинаются с "m" (при поиске не учитывается регистр).

Image12

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

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

Image13

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

Image14

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