Introdução com o Entity Framework 4.0 Database First e ASP.NET 4 Web Forms – Parte 3

por Tom Dykstra

O aplicativo Web de exemplo da Contoso University demonstra como criar aplicativos ASP.NET Web Forms usando o Entity Framework 4.0 e o Visual Studio 2010. Para obter informações sobre a série de tutoriais, consulte o primeiro tutorial da série

Filtragem, ordenação e agrupamento de dados

No tutorial anterior, você usou o EntityDataSource controle para exibir e editar dados. Neste tutorial, você filtrará, ordenará e agrupará dados. Quando você faz isso definindo as EntityDataSource propriedades do controle, a sintaxe é diferente de outros controles de fonte de dados. Como você verá, no entanto, você pode usar o QueryExtender controle para minimizar essas diferenças.

Você alterará a página Students.aspx para filtrar alunos, classificar por nome e pesquisar no nome. Você também alterará a página Courses.aspx para exibir cursos para o departamento selecionado e pesquisar cursos por nome. Por fim, você adicionará estatísticas de alunos à página About.aspx .

Captura de tela da janela Explorer da Internet, que mostra o modo de exibição Lista de Alunos com uma tabela de alunos.

Captura de tela da janela Explorer da Internet, que mostra os modos de exibição Cursos por Departamento e Cursos por Nome.

Captura de tela da janela Explorer da Internet, que mostra a exibição Estatísticas do Corpo do Aluno com uma tabela de datas de inscrição.

Captura de tela da janela Explorer da Internet, que mostra a exibição Localizar Alunos por Nome com a letra g inserida na consulta de pesquisa.

Usando a propriedade "Where" EntityDataSource para filtrar dados

Abra a página Students.aspx que você criou no tutorial anterior. Conforme configurado no momento, o GridView controle na página exibe todos os nomes do People conjunto de entidades. No entanto, você deseja mostrar apenas os alunos, que podem ser encontrados selecionando Person entidades que têm datas de inscrição não nulas.

Alterne para o modo design e selecione o EntityDataSource controle . Na janela Propriedades, defina a propriedade Where como it.EnrollmentDate is not null.

Imagem01

A sintaxe usada na Where propriedade do EntityDataSource controle é Entity SQL. O Entity SQL é semelhante ao Transact-SQL, mas é personalizado para uso com entidades em vez de objetos de banco de dados. Na expressão it.EnrollmentDate is not null, a palavra it representa uma referência à entidade retornada pela consulta. Portanto, it.EnrollmentDate refere-se à EnrollmentDate propriedade da Person entidade que o EntityDataSource controle retorna.

Execute a página. A lista de alunos agora contém apenas alunos. (Não há linhas exibidas em que não há data de registro.)

Captura de tela da janela Explorer da Internet, que mostra a exibição Lista de Alunos com uma tabela de alunos.

Usando a propriedade "OrderBy" do EntityDataSource para ordenar dados

Você também deseja que essa lista esteja em ordem de nome quando ela for exibida pela primeira vez. Com a página Students.aspx ainda aberta no modo Design e com o EntityDataSource controle ainda selecionado, na janela Propriedades , defina a propriedade OrderBy como it.LastName.

Imagem05

Execute a página. A lista de alunos agora está em ordem por sobrenome.

Imagem04

Usando um parâmetro de controle para definir a propriedade "Where"

Assim como acontece com outros controles de fonte de dados, você pode passar valores de parâmetro para a Where propriedade . Na página Courses.aspx que você criou na parte 2 do tutorial, você pode usar esse método para exibir cursos associados ao departamento que um usuário seleciona na lista suspensa.

Abra Courses.aspx e alterne para o modo design . Adicione um segundo EntityDataSource controle à página e nomeie-o CoursesEntityDataSourcecomo . Conecte-o ao SchoolEntities modelo e selecione Courses como o valor EntitySetName .

Na janela Propriedades , clique nas reticências na caixa propriedade Where . (Verifique se o CoursesEntityDataSource controle ainda está selecionado antes de usar a janela Propriedades .)

Image06

A caixa de diálogo Editor de Expressões é exibida. Nesta caixa de diálogo, selecione Gerar automaticamente a expressão Where com base nos parâmetros fornecidos e clique em Adicionar Parâmetro. Nomeie o parâmetro DepartmentID, selecione Controle como o valor de origem do parâmetro e selecione DepartmentsDropDownList como o valor ControlID .

Imagem07

Clique em Mostrar propriedades avançadas e, na janela Propriedades da caixa de diálogo Editor de Expressões, altere a Type propriedade para .Int32

Imagem15

Quando terminar, clique em OK.

Abaixo da lista suspensa, adicione um GridView controle à página e nomeie-o CoursesGridViewcomo . Conecte-o ao controle da CoursesEntityDataSource fonte de dados, clique em Atualizar Esquema, clique em Editar Colunas e remova a DepartmentID coluna. A GridView marcação de controle é semelhante ao exemplo a seguir.

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

Quando o usuário altera o departamento selecionado na lista suspensa, você deseja que a lista de cursos associados seja alterada automaticamente. Para fazer isso acontecer, selecione a lista suspensa e, na janela Propriedades , defina a AutoPostBack propriedade como True.

Imagem08

Agora que você terminou de usar o designer, alterne para Exibição de origem e substitua as ConnectionString propriedades e DefaultContainer nome do CoursesEntityDataSource controle pelo ContextTypeName="ContosoUniversity.DAL.SchoolEntities" atributo . Quando terminar, a marcação do controle será semelhante ao exemplo a seguir.

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

Execute a página e use a lista suspensa para selecionar diferentes departamentos. Somente os cursos oferecidos pelo departamento selecionado são exibidos no GridView controle .

Imagem09

Usando a propriedade "GroupBy" EntityDataSource para agrupar dados

Suponha que a Universidade Contoso queira colocar algumas estatísticas do corpo estudantil em sua página Sobre. Especificamente, ele deseja mostrar um detalhamento do número de alunos até a data em que se inscreveram.

Abra About.aspx e, no modo de exibição Origem , substitua o conteúdo existente do BodyContent controle por "Estatísticas do Corpo do Aluno" entre h2 marcas:

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

Após o título, adicione um EntityDataSource controle e nomeie-o StudentStatisticsEntityDataSourcecomo . Conecte-o ao SchoolEntities, selecione o People conjunto de entidades e deixe a caixa Selecionar no assistente inalterada. Defina as seguintes propriedades na janela Propriedades :

  • Para filtrar somente para alunos, defina a Where propriedade como it.EnrollmentDate is not null.
  • Para agrupar os resultados pela data de registro, defina a GroupBy propriedade como it.EnrollmentDate.
  • Para selecionar a data de inscrição e o número de alunos, defina a Select propriedade como it.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents.
  • Para ordenar os resultados pela data de registro, defina a OrderBy propriedade como it.EnrollmentDate.

No modo de exibição Origem , substitua as ConnectionString propriedades e DefaultContainer name por uma ContextTypeName propriedade . A EntityDataSource marcação de controle agora se assemelha ao exemplo a seguir.

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

A sintaxe das Selectpropriedades , GroupBye Where é semelhante ao Transact-SQL, exceto pelo it palavra-chave que especifica a entidade atual.

Adicione a marcação a seguir para criar um GridView controle para exibir os dados.

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

Execute a página para ver uma lista mostrando o número de alunos por data de inscrição.

Captura de tela da janela Explorer da Internet, que mostra a exibição Estatísticas do Corpo do Aluno com uma tabela de datas de registro.

Usando o controle QueryExtender para filtragem e ordenação

O QueryExtender controle fornece uma maneira de especificar filtragem e classificação na marcação. A sintaxe é independente do DBMS (sistema de gerenciamento de banco de dados) que você está usando. Ele também geralmente é independente do Entity Framework, com exceção de que a sintaxe usada para propriedades de navegação é exclusiva do Entity Framework.

Nesta parte do tutorial, você usará um QueryExtender controle para filtrar e ordenar dados, e um dos campos order-by será uma propriedade de navegação.

(Se você preferir usar o código em vez de marcar para estender as consultas geradas automaticamente pelo EntityDataSource controle, poderá fazer isso manipulando o QueryCreated evento. É assim que o QueryExtender controle estende EntityDataSource também as consultas de controle.)

Abra a página Courses.aspx e, abaixo da marcação que você adicionou anteriormente, insira a marcação a seguir para criar um título, uma caixa de texto para inserir cadeias de caracteres de pesquisa, um botão de pesquisa e um EntityDataSource controle associado ao Courses conjunto de entidades.

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

Observe que a EntityDataSource propriedade do Include controle está definida como Department. No banco de dados, a Course tabela não contém o nome do departamento; ela contém uma DepartmentID coluna de chave estrangeira. Se você estivesse consultando o banco de dados diretamente, para obter o nome do departamento junto com os dados do curso, teria que unir as Course tabelas e Department . Ao definir a Include propriedade como Department, especifique que o Entity Framework deve fazer o trabalho de obter a entidade relacionada Department quando ela obtém uma Course entidade. Em Department seguida, a entidade é armazenada na Department propriedade de navegação da Course entidade. (Por padrão, a SchoolEntities classe que foi gerada pelo designer de modelo de dados recupera dados relacionados quando necessário e você vinculou o controle da fonte de dados a essa classe, portanto, a definição da Include propriedade não é necessária. No entanto, defini-la melhora o desempenho da página, pois caso contrário, o Entity Framework faria chamadas separadas para o banco de dados para recuperar dados para as Course entidades e para as entidades relacionadas Department .)

Após o EntityDataSource controle que você acabou de criar, insira a marcação a seguir para criar um QueryExtender controle associado a esse EntityDataSource controle.

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

O SearchExpression elemento especifica que você deseja selecionar cursos cujos títulos correspondem ao valor inserido na caixa de texto. Somente quantos caracteres forem inseridos na caixa de texto serão comparados, pois a SearchType propriedade especifica StartsWith.

O OrderByExpression elemento especifica que o conjunto de resultados será ordenado pelo título do curso no nome do departamento. Observe como o nome do departamento é especificado: Department.Name. Como a associação entre a Course entidade e a Department entidade é um para um, a Department propriedade de navegação contém uma Department entidade. (Se essa fosse uma relação um-para-muitos, a propriedade conteria uma coleção.) Para obter o nome do departamento, você deve especificar a Name propriedade da Department entidade.

Por fim, adicione um GridView controle para exibir a lista de cursos:

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

A primeira coluna é um campo de modelo que exibe o nome do departamento. A expressão de vinculação de dados especifica Department.Name, assim como você viu no QueryExtender controle .

Execute a página. A exibição inicial mostra uma lista de todos os cursos em ordem por departamento e, em seguida, pelo título do curso.

Captura de tela da janela Explorer da Internet, que mostra os modos de exibição Cursos por Departamento e Cursos por Nome.

Insira um "m" e clique em Pesquisar para ver todos os cursos cujos títulos começam com "m" (a pesquisa não diferencia maiúsculas de minúsculas).

Imagem12

Usando o operador "Like" para filtrar dados

Você pode obter um efeito semelhante aos QueryExtender tipos de pesquisa , Containse EndsWith do StartsWithcontrole usando um Like operador na EntityDataSource propriedade do Where controle. Nesta parte do tutorial, você verá como usar o Like operador para pesquisar um aluno por nome.

Abra Students.aspx no modo de exibição De origem . Após o GridView controle, adicione a seguinte marcação:

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

Essa marcação é semelhante ao que você viu anteriormente, exceto pelo valor da Where propriedade. A segunda parte da Where expressão define uma pesquisa de subcadeia de caracteres (LIKE %FirstMidName% or LIKE %LastName%) que pesquisa os nomes primeiro e sobrenome para o que for inserido na caixa de texto.

Execute a página. Inicialmente, você vê todos os alunos porque o valor padrão para o StudentName parâmetro é "%".

Imagem13

Insira a letra "g" na caixa de texto e clique em Pesquisar. Você vê uma lista de alunos que têm um "g" no nome ou sobrenome.

Captura de tela da janela Explorer da Internet, que mostra a exibição Localizar Alunos por Nome com a letra g inserida na consulta de pesquisa.

Agora você exibiu, atualizou, filtraram, ordenaram e agruparam dados de tabelas individuais. No próximo tutorial, você começará a trabalhar com dados relacionados (cenários master detalhes).