Uso de Entity Framework 4.0 y el control ObjectDataSource, parte 3: Ordenar y filtrar
de Tom Dykstra
Esta serie de tutoriales se basa en la aplicación web Contoso University creada por la Introducción a Entity Framework 4.0 serie de tutoriales. Si no completó los tutoriales anteriores, como punto de partida de este tutorial, puede descargar la aplicación que habría creado. También puede descargar la aplicación creada mediante la serie de tutoriales completados. Si tiene preguntas sobre los tutoriales, puede publicarlas en el foro de ASP.NET Entity Framework.
En el tutorial anterior implementó el patrón de repositorio en una aplicación web de n niveles que usa Entity Framework y el ObjectDataSource
control. En este tutorial se muestra cómo realizar la ordenación y el filtrado y controlar escenarios de detalles maestros. Agregará las siguientes mejoras a la página de Departments.aspx:
- Cuadro de texto para permitir que los usuarios seleccionen departamentos por nombre.
- Lista de cursos para cada departamento que se muestra en la cuadrícula.
- La capacidad de ordenar haciendo clic en encabezados de columna.
Adición de la capacidad de ordenar columnas GridView
Abra la página Departments.aspx y agregue un SortParameterName="sortExpression"
atributo al ObjectDataSource
control denominado DepartmentsObjectDataSource
. (Más adelante creará un GetDepartments
método que toma un parámetro denominado sortExpression
). El marcado de la etiqueta de apertura del control ahora es similar al ejemplo siguiente.
<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server"
TypeName="ContosoUniversity.BLL.SchoolBL" DataObjectTypeName="ContosoUniversity.DAL.Department"
SelectMethod="GetDepartments" DeleteMethod="DeleteDepartment" UpdateMethod="UpdateDepartment"
ConflictDetection="CompareAllValues" OldValuesParameterFormatString="orig{0}"
OnUpdated="DepartmentsObjectDataSource_Updated" SortParameterName="sortExpression" >
Agregue el AllowSorting="true"
atributo a la etiqueta de apertura del GridView
control. El marcado de la etiqueta de apertura del control ahora es similar al ejemplo siguiente.
<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID"
OnRowUpdating="DepartmentsGridView_RowUpdating"
AllowSorting="true" >
En Departments.aspx.cs, establezca el criterio de ordenación predeterminado llamando al GridView
método del Sort
control desde el Page_Load
método:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DepartmentsGridView.Sort("Name", SortDirection.Ascending);
}
}
Puede agregar código que ordene o filtre en la clase lógica de negocios o en la clase de repositorio. Si lo hace en la clase lógica de negocios, el trabajo de ordenación o filtrado se realizará después de recuperar los datos de la base de datos, ya que la clase lógica de negocios funciona con un IEnumerable
objeto devuelto por el repositorio. Si agrega código de ordenación y filtrado en la clase de repositorio y lo hace antes de convertir una consulta de objeto o expresión LINQ en un IEnumerable
objeto, los comandos se pasarán a la base de datos para su procesamiento, lo que suele ser más eficaz. En este tutorial, implementará la ordenación y el filtrado de una manera que haga que la base de datos realice el procesamiento, es decir, en el repositorio.
Para agregar la funcionalidad de ordenación, debe agregar un nuevo método a la interfaz del repositorio y a las clases de repositorio, así como a la clase lógica de negocios. En el archivo ISchoolRepository.cs, agregue un nuevo GetDepartments
método que tome un sortExpression
parámetro que se usará para ordenar la lista de departamentos que se devuelven:
IEnumerable<Department> GetDepartments(string sortExpression);
El sortExpression
parámetro especificará la columna en la que se va a ordenar y la dirección de ordenación.
Agregue código para el nuevo método al archivo SchoolRepository.cs:
public IEnumerable<Department> GetDepartments(string sortExpression)
{
if (String.IsNullOrWhiteSpace(sortExpression))
{
sortExpression = "Name";
}
return context.Departments.Include("Person").OrderBy("it." + sortExpression).ToList();
}
Cambie el método sin GetDepartments
parámetros existente para llamar al nuevo método:
public IEnumerable<Department> GetDepartments()
{
return GetDepartments("");
}
En el proyecto de prueba, agregue el siguiente método nuevo a MockSchoolRepository.cs:
public IEnumerable<Department> GetDepartments(string sortExpression)
{
return departments;
}
Si va a crear pruebas unitarias que dependan de este método que devuelvan una lista ordenada, deberá ordenar la lista antes de devolverla. No va a crear pruebas como las de este tutorial, por lo que el método solo puede devolver la lista de departamentos no ordenados.
En el archivo SchoolBL.cs, agregue el siguiente método nuevo a la clase lógica de negocios:
public IEnumerable<Department> GetDepartments(string sortExpression)
{
return schoolRepository.GetDepartments(sortExpression);
}
Este código pasa el parámetro de ordenación al método de repositorio.
Ejecute la página Departments.aspx.
Ahora puede hacer clic en cualquier encabezado de columna para ordenar por esa columna. Si la columna ya está ordenada, al hacer clic en el encabezado se invierte la dirección de ordenación.
Agregar un cuadro de búsqueda
En esta sección agregará un cuadro de texto de búsqueda, lo vinculará al ObjectDataSource
control mediante un parámetro de control y agregará un método a la clase lógica de negocios para admitir el filtrado.
Abra la página Departments.aspx y agregue el marcado siguiente entre el encabezado y el primer ObjectDataSource
control:
Enter any part of the name or leave the box blank to see all names:
<asp:TextBox ID="SearchTextBox" runat="server" AutoPostBack="true"></asp:TextBox>
<asp:Button ID="SearchButton" runat="server" Text="Search" />
En el ObjectDataSource
control denominado DepartmentsObjectDataSource
, haga lo siguiente:
- Agregue un
SelectParameters
elemento para un parámetro denominadonameSearchString
que obtiene el valor especificado en elSearchTextBox
control. - Cambie el
SelectMethod
valor del atributo aGetDepartmentsByName
. (Creará este método más adelante).
El marcado del ObjectDataSource
control ahora es similar al ejemplo siguiente:
<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server" TypeName="ContosoUniversity.BLL.SchoolBL"
SelectMethod="GetDepartmentsByName" DeleteMethod="DeleteDepartment" UpdateMethod="UpdateDepartment"
DataObjectTypeName="ContosoUniversity.DAL.Department" ConflictDetection="CompareAllValues"
SortParameterName="sortExpression" OldValuesParameterFormatString="orig{0}"
OnUpdated="DepartmentsObjectDataSource_Updated">
<SelectParameters>
<asp:ControlParameter ControlID="SearchTextBox" Name="nameSearchString" PropertyName="Text"
Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
En ISchoolRepository.cs, añada un GetDepartmentsByName
método que tome los parámetros sortExpression
y nameSearchString
:
IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString);
En SchoolRepository.cs, añada el siguiente método nuevo:
public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
if (String.IsNullOrWhiteSpace(sortExpression))
{
sortExpression = "Name";
}
if (String.IsNullOrWhiteSpace(nameSearchString))
{
nameSearchString = "";
}
return context.Departments.Include("Person").OrderBy("it." + sortExpression).Where(d => d.Name.Contains(nameSearchString)).ToList();
}
Este código usa un Where
método para seleccionar elementos que contengan la cadena de búsqueda. Si la cadena de búsqueda está vacía, se seleccionarán todos los registros. Tenga en cuenta que cuando se especifican llamadas de método juntas en una instrucción como esta (Include
, a continuación OrderBy
, a continuación Where
), el Where
método siempre debe ser el último.
Cambie el método existente GetDepartments
que toma un sortExpression
parámetro para llamar al nuevo método:
public IEnumerable<Department> GetDepartments(string sortExpression)
{
return GetDepartmentsByName(sortExpression, "");
}
En MockSchoolRepository.cs del proyecto de prueba, agregue el siguiente método nuevo:
public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
return departments;
}
En SchoolBL.cs, agregue el siguiente método nuevo:
public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
return schoolRepository.GetDepartmentsByName(sortExpression, nameSearchString);
}
Ejecute la página Departments.aspx y escriba una cadena de búsqueda para asegurarse de que la lógica de selección funciona. Deje el cuadro de texto vacío e intente buscar para asegurarse de que se devuelven todos los registros.
Agregar una columna de detalles para cada fila de cuadrícula
A continuación, quiere ver todos los cursos de cada departamento que se muestran en la celda derecha de la cuadrícula. Para ello, usará un GridView
control anidado y lo enlazará a los datos de la Courses
propiedad de navegación de la Department
entidad.
Abra Departments.aspx y, en el marcado del GridView
control, especifique un controlador para el RowDataBound
evento. El marcado de la etiqueta de apertura del control ahora es similar al ejemplo siguiente.
<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID"
OnRowUpdating="DepartmentsGridView_RowUpdating"
OnRowDataBound="DepartmentsGridView_RowDataBound"
AllowSorting="True" >
Agregue un nuevo TemplateField
elemento después del Administrator
campo de plantilla:
<asp:TemplateField HeaderText="Courses">
<ItemTemplate>
<asp:GridView ID="CoursesGridView" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="CourseID" HeaderText="ID" />
<asp:BoundField DataField="Title" HeaderText="Title" />
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
Este marcado crea un control anidado GridView
que muestra el número de curso y el título de una lista de cursos. No especifica un origen de datos porque lo enlazará en el código del RowDataBound
controlador.
Abra Departments.aspx.cs y agregue el controlador siguiente para el RowDataBound
evento:
protected void DepartmentsGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var department = e.Row.DataItem as Department;
var coursesGridView = (GridView)e.Row.FindControl("CoursesGridView");
coursesGridView.DataSource = department.Courses.ToList();
coursesGridView.DataBind();
}
}
Este código obtiene la Department
entidad de los argumentos de evento, convierte la Courses
propiedad de navegación en una List
colección y los enlaces de datos anidados GridView
a la colección.
Abra el archivo SchoolRepository.cs y especifique la carga diligente de la Courses
propiedad de navegación llamando al Include
método en la consulta de objeto que se crea en el GetDepartmentsByName
método. La return
instrucción del GetDepartmentsByName
método ahora es similar al ejemplo siguiente.
return context.Departments.Include("Person").Include("Courses").
OrderBy("it." + sortExpression).Where(d => d.Name.Contains(nameSearchString)).ToList();
Ejecute la página. Además de la funcionalidad de ordenación y filtrado que agregó anteriormente, el control GridView ahora muestra los detalles del curso anidados para cada departamento.
Esto completa la introducción a los escenarios de ordenación, filtrado y detalles maestros. En el siguiente tutorial verá cómo tratar la simultaneidad.
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de