Начало работы с Entity Framework 4,0 Database First и веб-форм ASP.NET 4. часть 3Getting Started with Entity Framework 4.0 Database First and ASP.NET 4 Web Forms - Part 3

от Tom Dykstra)by Tom Dykstra

Пример веб-приложения университета Contoso демонстрирует создание приложений ASP.NET Web Forms с помощью Entity Framework 4,0 и Visual Studio 2010.The Contoso University sample web application demonstrates how to create ASP.NET Web Forms applications using the Entity Framework 4.0 and Visual Studio 2010. Сведения о серии руководств см. в первом учебнике серии .For information about the tutorial series, see the first tutorial in the series

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

В предыдущем учебнике для просмотра и изменения данных использовался элемент управления EntityDataSource.In the previous tutorial you used the EntityDataSource control to display and edit data. В этом учебнике вы будете фильтровать, упорядочивать и группировать данные.In this tutorial you'll filter, order, and group data. При этом при установке свойств элемента управления EntityDataSource синтаксис отличается от других элементов управления источниками данных.When you do this by setting properties of the EntityDataSource control, the syntax is different from other data source controls. Но вы увидите, что для сворачивания этих различий можно использовать элемент управления QueryExtender.As you'll see, however, you can use the QueryExtender control to minimize these differences.

Вы измените страницу students. aspx , чтобы отфильтровать учащихся, сортировать по имени и искать по имени.You'll change the Students.aspx page to filter for students, sort by name, and search on name. Вы также измените страницу Courses. aspx , чтобы отобразить курсы для выбранного отдела и найти курсы по имени.You'll also change the Courses.aspx page to display courses for the selected department and search for courses by name. Наконец, вы добавите статистику для учащихся на страницу About. aspx .Finally, you'll add student statistics to the About.aspx page.

Image02Image02

Image11Image11

Image10Image10

Image14Image14

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

Откройте страницу students. aspx , созданную в предыдущем руководстве.Open the Students.aspx page that you created in the previous tutorial. Как уже настроено, элемент управления GridView на странице отображает все имена из People набора сущностей.As currently configured, the GridView control in the page displays all the names from the People entity set. Однако вы хотите показывать только учащихся, которые можно найти, выбрав Person сущности с датами регистрации, отличными от NULL.However, you want to show only students, which you can find by selecting Person entities that have non-null enrollment dates.

Перейдите в режим конструктора и выберите элемент управления EntityDataSource.Switch to Design view and select the EntityDataSource control. В окне Свойства присвойте свойству Where значение it.EnrollmentDate is not null.In the Properties window, set the Where property to it.EnrollmentDate is not null.

image01Image01

Синтаксис, используемый в свойстве Where элемента управления EntityDataSource, Entity SQL.The syntax you use in the Where property of the EntityDataSource control is Entity SQL. Entity SQL похож на Transact-SQL, но он настроен для использования с сущностями, а не с объектами базы данных.Entity SQL is similar to Transact-SQL, but it's customized for use with entities rather than database objects. В it.EnrollmentDate is not nullе выражения слово it представляет ссылку на сущность, возвращенную запросом.In the expression it.EnrollmentDate is not null, the word it represents a reference to the entity returned by the query. Таким образом, it.EnrollmentDate ссылается на свойство EnrollmentDate сущности Person, которую возвращает элемент управления EntityDataSource.Therefore, it.EnrollmentDate refers to the EnrollmentDate property of the Person entity that the EntityDataSource control returns.

Запустите страницу.Run the page. Список учащихся теперь содержит только учащихся.The students list now contains only students. (Нет строк, которые отображаются там, где нет даты регистрации.)(There are no rows displayed where there's no enrollment date.)

Image02Image02

Использование свойства EntityDataSource "OrderBy" для упорядочивания данныхUsing the EntityDataSource "OrderBy" Property to Order Data

Кроме того, при первом отображении список должен находиться в порядке имен.You also want this list to be in name order when it's first displayed. Если страница students. aspx по-прежнему открыта в режиме конструктора и элемент управления EntityDataSource по-прежнему выбран, в окне Свойства задайте для свойства OrderBy значение it.LastName.With the Students.aspx page still open in Design view, and with the EntityDataSource control still selected, in the Properties window set the OrderBy property to it.LastName.

Image05Image05

Запустите страницу.Run the page. Список учащихся теперь находится в порядке фамилии.The students list is now in order by last name.

Image04Image04

Использование параметра элемента управления для задания свойства "Where"Using a Control Parameter to Set the "Where" Property

Как и в случае с другими элементами управления источниками данных, значения параметров можно передать свойству Where.As with other data source controls, you can pass parameter values to the Where property. На странице Courses. aspx , созданной в части 2 этого руководства, этот метод можно использовать для просмотра курсов, связанных с подразделением, которое пользователь выбирает из раскрывающегося списка.On the Courses.aspx page that you created in part 2 of the tutorial, you can use this method to display courses that are associated with the department that a user selects from the drop-down list.

Откройте страницу Courses. aspx и переключитесь в режим конструктора .Open Courses.aspx and switch to Design view. Добавьте второй элемент управления EntityDataSource на страницу и присвойте ему имя CoursesEntityDataSource.Add a second EntityDataSource control to the page, and name it CoursesEntityDataSource. Подключите его к модели SchoolEntities и выберите Courses в качестве значения EntitySetName .Connect it to the SchoolEntities model, and select Courses as the EntitySetName value.

В окне Свойства нажмите кнопку с многоточием в поле свойства WHERE .In the Properties window, click the ellipsis in the Where property box. (Перед использованием окна свойств убедитесь, что элемент управления CoursesEntityDataSource выбран.)(Make sure the CoursesEntityDataSource control is still selected before using the Properties window.)

Image06Image06

Откроется диалоговое окно Редактор выражений .The Expression Editor dialog box is displayed. В этом диалоговом окне выберите автоматически создать выражение WHERE на основе указанных параметров, а затем нажмите кнопку Добавить параметр.In this dialog box, select Automatically generate the Where expression based on the provided parameters, and then click Add Parameter. Присвойте параметру имя DepartmentID, выберите элемент управления в качестве значения источника параметра и выберите департментсдропдовнлист в качестве значения ControlID .Name the parameter DepartmentID, select Control as the Parameter source value, and select DepartmentsDropDownList as the ControlID value.

Image07Image07

Нажмите кнопку " отобразить дополнительные свойства" и в окне " свойства " диалогового окна редактор выражений измените значение свойства Type на Int32.Click Show advanced properties, and in the Properties window of the Expression Editor dialog box, change the Type property to Int32.

Image15Image15

Закончив, нажмите кнопку OK.When you're done, click OK.

Ниже раскрывающегося списка добавьте элемент управления GridView на страницу и присвойте ему имя CoursesGridView.Below the drop-down list, add a GridView control to the page and name it CoursesGridView. Подключите его к CoursesEntityDataSource элементу управления источниками данных, щелкните Обновить схему, щелкните изменить столбцыи удалите столбец DepartmentID.Connect it to the CoursesEntityDataSource data source control, click Refresh Schema, click Edit Columns, and remove the DepartmentID column. Разметка элемента управления GridView напоминает следующий пример.The GridView control markup resembles the following example.

<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>

Когда пользователь изменяет выбранное подразделение в раскрывающемся списке, необходимо, чтобы список связанных курсов был изменен автоматически.When the user changes the selected department in the drop-down list, you want the list of associated courses to change automatically. Чтобы сделать это, выберите раскрывающийся список и в окне Свойства задайте для свойства AutoPostBack значение True.To make this happen, select the drop-down list, and in the Properties window set the AutoPostBack property to True.

Image08Image08

После завершения работы с конструктором переключитесь в представление исходного кода и замените свойства ConnectionString и DefaultContainer имени элемента управления CoursesEntityDataSource атрибутом ContextTypeName="ContosoUniversity.DAL.SchoolEntities".Now that you're finished using the designer, switch to Source view and replace the ConnectionString and DefaultContainer name properties of the CoursesEntityDataSource control with the ContextTypeName="ContosoUniversity.DAL.SchoolEntities" attribute. По завершении разметка элемента управления будет выглядеть, как в следующем примере.When you're done, the markup for the control will look like the following example.

<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>

Запустите страницу и используйте раскрывающийся список для выбора различных отделов.Run the page and use the drop-down list to select different departments. В элементе управления GridView отображаются только те курсы, которые предлагаются выбранным Отделом.Only courses that are offered by the selected department are displayed in the GridView control.

Image09Image09

Использование свойства EntityDataSource "GroupBy" для группирования данныхUsing the EntityDataSource "GroupBy" Property to Group Data

Предположим, что университет Contoso хочет разместить на странице About некоторую статистику на основе текста учащихся.Suppose Contoso University wants to put some student-body statistics on its About page. В частности, он хочет показать подразделение количества учащихся на дату их регистрации.Specifically, it wants to show a breakdown of numbers of students by the date they enrolled.

Откройте About. aspxи в представлении исходного кода замените существующее содержимое элемента управления BodyContent на "Статистика текста учащегося" между тегами h2:Open About.aspx, and in Source view, replace the existing contents of the BodyContent control with "Student Body Statistics" between h2 tags:

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>Student Body Statistics</h2>
</asp:Content>

После заголовка добавьте элемент управления EntityDataSource и присвойте ему имя StudentStatisticsEntityDataSource.After the heading, add an EntityDataSource control and name it StudentStatisticsEntityDataSource. Подключите его к SchoolEntities, выберите People набор сущностей и оставьте поле выбора в мастере без изменений.Connect it to SchoolEntities, select the People entity set, and leave the Select box in the wizard unchanged. Задайте следующие свойства в окне " Свойства ":Set the following properties in the Properties window:

  • Чтобы выполнить фильтрацию только для учащихся, задайте для свойства Where значение it.EnrollmentDate is not null.To filter for students only, set the Where property to it.EnrollmentDate is not null.
  • Чтобы сгруппировать результаты по дате регистрации, задайте для свойства GroupBy значение it.EnrollmentDate.To group the results by the enrollment date, set the GroupBy property to it.EnrollmentDate.
  • Чтобы выбрать дату регистрации и число учащихся, задайте для свойства Select значение it.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents.To select the enrollment date and the number of students, set the Select property to it.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents.
  • Чтобы упорядочить результаты по дате регистрации, задайте для свойства OrderBy значение it.EnrollmentDate.To order the results by the enrollment date, set the OrderBy property to it.EnrollmentDate.

В представлении исходного кода замените свойства ConnectionString и DefaultContainer именем свойством ContextTypeName.In Source view, replace the ConnectionString and DefaultContainer name properties with a ContextTypeName property. Разметка элемента управления EntityDataSource теперь напоминает следующий пример.The EntityDataSource control markup now resembles the following example.

<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, определяющего текущую сущность.The syntax of the Select, GroupBy, and Where properties resembles Transact-SQL except for the it keyword that specifies the current entity.

Добавьте следующую разметку, чтобы создать GridView элемент управления для вывода данных.Add the following markup to create a GridView control to display the data.

<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>

Запустите страницу, чтобы просмотреть список, отображающий число учащихся по дате регистрации.Run the page to see a list showing the number of students by enrollment date.

Image10Image10

Использование элемента управления элемента для фильтрации и упорядоченияUsing the QueryExtender Control for Filtering and Ordering

Элемент управления QueryExtender предоставляет способ задания фильтрации и сортировки в разметке.The QueryExtender control provides a way to specify filtering and sorting in markup. Синтаксис не зависит от используемой системы управления базами данных (СУБД).The syntax is independent of the database management system (DBMS) you're using. Обычно он не зависит от Entity Framework, за исключением того, что синтаксис, используемый для свойств навигации, уникален для Entity Framework.It's also generally independent of the Entity Framework, with the exception that syntax you use for navigation properties is unique to the Entity Framework.

В этой части учебника будет использоваться элемент управления QueryExtender для фильтрации и упорядочения данных, а одно из полей ORDER-BY — это свойство навигации.In this part of the tutorial you'll use a QueryExtender control to filter and order data, and one of the order-by fields will be a navigation property.

(Если вы предпочитаете использовать код вместо разметки для расширения запросов, автоматически создаваемых элементом управления EntityDataSource, это можно сделать, обрабатывая событие QueryCreated.(If you prefer to use code instead of markup to extend the queries that are automatically generated by the EntityDataSource control, you can do that by handling the QueryCreated event. Именно так QueryExtender элемент управления расширяет запросы EntityDataSource Control.)This is how the QueryExtender control extends EntityDataSource control queries also.)

Откройте страницу Courses. aspx и под добавленной ранее разметкой вставьте следующую разметку, чтобы создать заголовок, текстовое поле для ввода строк поиска, кнопку поиска и элемент управления EntityDataSource, привязанный к Coursesному набору сущностей.Open the Courses.aspx page, and below the markup you added previously, insert the following markup to create a heading, a text box for entering search strings, a search button, and an EntityDataSource control that's bound to the Courses entity set.

<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.Notice that the EntityDataSource control's Include property is set to Department. В базе данных Course таблица не содержит название отдела; Он содержит DepartmentID столбец внешнего ключа.In the database, the Course table does not contain the department name; it contains a DepartmentID foreign key column. Если вы напрямую запрашиваете базу данных, чтобы получить имя отдела вместе с данными курса, необходимо объединить Course и Department таблицы.If you were querying the database directly, to get the department name along with course data, you would have to join the Course and Department tables. Установив для свойства Include значение Department, вы указываете, что Entity Framework должен выполнять работу по получению связанной Department сущности, когда она получает Course сущность.By setting the Include property to Department, you specify that the Entity Framework should do the work of getting the related Department entity when it gets a Course entity. Затем сущность Department сохраняется в свойстве навигации Department сущности Course.The Department entity is then stored in the Department navigation property of the Course entity. (По умолчанию класс SchoolEntities, созданный конструктором моделей данных, извлекает связанные данные, когда это необходимо, и вы привязываете элемент управления источником данных к этому классу, поэтому установка свойства Include не требуется.(By default, the SchoolEntities class that was generated by the data model designer retrieves related data when it's needed, and you've bound the data source control to that class, so setting the Include property is not necessary. Однако установка этого параметра повышает производительность страницы, так как в противном случае Entity Framework будет выполнять отдельные вызовы к базе данных для получения данных для Course сущностей и связанных сущностей Department.)However, setting it improves performance of the page, because otherwise the Entity Framework would make separate calls to the database to retrieve data for the Course entities and for the related Department entities.)

После только что созданного элемента управления EntityDataSource вставьте следующую разметку, чтобы создать элемент управления QueryExtender, привязанный к этому элементу управления EntityDataSource.After the EntityDataSource control you just created, insert the following markup to create a QueryExtender control that's bound to that EntityDataSource control.

<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 указывает, что необходимо выбрать курсы, заголовки которых соответствуют значению, введенному в текстовом поле.The SearchExpression element specifies that you want to select courses whose titles match the value entered in the text box. Будет сравниваться только число символов, указанное в текстовом поле, так как свойство SearchType указывает StartsWith.Only as many characters as are entered in the text box will be compared, because the SearchType property specifies StartsWith.

Элемент OrderByExpression указывает, что результирующий набор будет упорядочен по названию курса в названии отдела.The OrderByExpression element specifies that the result set will be ordered by course title within department name. Обратите внимание на то, как указано название отдела: Department.Name.Notice how department name is specified: Department.Name. Поскольку связь между сущностью Course и сущностью Department является "один к одному", свойство навигации Department содержит сущность Department.Because the association between the Course entity and the Department entity is one-to-one, the Department navigation property contains a Department entity. (Если это связь «один ко многим», свойство будет содержать коллекцию.) Чтобы получить имя отдела, необходимо указать свойство Name сущности Department.(If this were a one-to-many relationship, the property would contain a collection.) To get the department name, you must specify the Name property of the Department entity.

Наконец, добавьте элемент управления GridView для просмотра списка курсов:Finally, add a GridView control to display the list of courses:

<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>

Первый столбец — это поле шаблона, в котором отображается название отдела.The first column is a template field that displays the department name. Выражение DataBinding задает Department.Name, как показано в элементе управления QueryExtender.The databinding expression specifies Department.Name, just as you saw in the QueryExtender control.

Запустите страницу.Run the page. В начальном отображении отображается список всех курсов, упорядоченных по отделам, а затем по названию курса.The initial display shows a list of all courses in order by department and then by course title.

Image11Image11

Введите "m" и нажмите кнопку " Поиск ", чтобы просмотреть все курсы, названия которых начинаются с "m" (при поиске не учитывается регистр).Enter an "m" and click Search to see all courses whose titles begin with "m" (the search is not case sensitive).

Image12Image12

Использование оператора LIKE для фильтрации данныхUsing the "Like" Operator to Filter Data

С помощью оператора Like в свойстве EntityDataSource элемента управления Where можно добиться того же результата, что и для типов поиска StartsWith, Containsи EndsWith элемента управления QueryExtender.You can achieve an effect similar to the QueryExtender control's StartsWith, Contains, and EndsWith search types by using a Like operator in the EntityDataSource control's Where property. В этой части руководства вы узнаете, как использовать оператор Like для поиска учащихся по имени.In this part of the tutorial, you'll see how to use the Like operator to search for a student by name.

Откройте students. aspx в представлении исходного кода .Open Students.aspx in Source view. После элемента управления GridView добавьте следующую разметку:After the GridView control, add the following markup:

<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.This markup is similar to what you've seen earlier except for the Where property value. Вторая часть выражения Where определяет Поиск подстроки (LIKE %FirstMidName% or LIKE %LastName%), которая выполняет поиск в первом и последнем именах, вводимых в текстовом поле.The second part of the Where expression defines a substring search (LIKE %FirstMidName% or LIKE %LastName%) that searches both the first and last names for whatever is entered in the text box.

Запустите страницу.Run the page. Сначала вы увидите всех учащихся, так как значение по умолчанию для параметра StudentName — "%".Initially you see all of the students because the default value for the StudentName parameter is "%".

Image13Image13

Введите букву "g" в текстовом поле и нажмите кнопку " Поиск".Enter the letter "g" in the text box and click Search. Вы увидите список учащихся, имеющих "g" в имени или фамилии.You see a list of students that have a "g" in either the first or last name.

Image14Image14

Теперь вы отображаете, обновили, отфильтрованные, упорядоченные и сгруппированные данные из отдельных таблиц.You've now displayed, updated, filtered, ordered, and grouped data from individual tables. В следующем учебнике вы начнете работать с связанными данными (сценарии "основной-подробности").In the next tutorial you'll begin to work with related data (master-detail scenarios).