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 .
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
.
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.)
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
.
Execute a página. A lista de alunos agora está em ordem por sobrenome.
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 CoursesEntityDataSource
como . 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 .)
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 .
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
Quando terminar, clique em OK.
Abaixo da lista suspensa, adicione um GridView
controle à página e nomeie-o CoursesGridView
como . 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
.
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 .
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 StudentStatisticsEntityDataSource
como . 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 comoit.EnrollmentDate is not null
. - Para agrupar os resultados pela data de registro, defina a
GroupBy
propriedade comoit.EnrollmentDate
. - Para selecionar a data de inscrição e o número de alunos, defina a
Select
propriedade comoit.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents
. - Para ordenar os resultados pela data de registro, defina a
OrderBy
propriedade comoit.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 Select
propriedades , GroupBy
e 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.
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.
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).
Usando o operador "Like" para filtrar dados
Você pode obter um efeito semelhante aos QueryExtender
tipos de pesquisa , Contains
e EndsWith
do StartsWith
controle 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 é "%".
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.
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).