OK, he pasado unos días en las malas hierbas con esta, y creo que tengo un control sobre ella.
Primero, una pieza importante de magia. Para que la paginación funcione correctamente, el buscapersonas debe conocer el recuento total de elementos, sin importar cuántos elementos devolvió la consulta actual. Si la consulta devuelve todo, el recuento de elementos es, obviamente, la cantidad de elementos devueltos. Para la paginación inteligente, el recuento de elementos sigue siendo el total de artículos disponibles, aunque la consulta solo devuelve lo que se muestra. Con el filtrado, incluso el total de elementos disponibles cambia cada vez que cambia el filtro.
El control Silverlight Datapager tiene una propiedad llamada ItemCount. Es de solo lectura y no se puede unir a datos en XAML, o establecer directamente en el código. Sin embargo, si el control de usuario que contiene el buscapersonas tiene un DataContext que implementa IPagedCollectionView, entonces el objeto de contexto de datos debe implementar una propiedad ItemCount con notificación PropertyChanged, y el DataPager parece recoger esto automágicamente.
En segundo lugar, recomiendo la excelente series of blog posts on RIA Services de Brad Abrams, especialmente esta en ViewModel. Contiene la mayor parte de lo que necesita para realizar el trabajo de paginación y filtrado, aunque le falta la pieza crítica para administrar el recuento de elementos. Su muestra descargable también contiene un muy buen marco básico para implementar ModelViewViewModel (MVVM). ¡Gracias, Brad!
Así que aquí está cómo hacer que el recuento de elementos funcione. (Este código hace referencia a un ORM personalizado, mientras que el código de Brad utiliza Entity Framework; entre los dos puede calcular lo que necesita en su entorno)
Primero, su ORM necesita admitir el recuento de registros, con y sin su filtrar. Aquí está mi código de servicio de dominio que hace que los recuentos a los Servicios RIA:
[Invoke]
public int GetExamCount()
{
return Context.Exams.Count();
}
[Invoke]
public int GetFilteredExamCount(string descriptionFilter)
{
return Context.Exams.GetFilteredCount(descriptionFilter);
}
Nota del [invocación] atributo. Lo necesita para cualquier método DomainService que no devuelva una entidad o una colección Entity.
Ahora para el código de ViewModel. Necesitas un ItemCount, por supuesto. (Esto es del ejemplo de Brad.)
int itemCount;
public int ItemCount
{
get { return itemCount; }
set
{
if (itemCount != value)
{
itemCount = value;
RaisePropertyChanged(ItemCountChangedEventArgs);
}
}
}
Su método LoadData se ejecute la consulta para obtener el conjunto actual de filas para mostrar en la cuadrícula de datos. (Esto no aplica la costumbre de clasificación todavía, pero eso es una adición fácil.)
EntityQuery<ExamEntity> query =
DomainContext.GetPagedExamsQuery(PageSize * PageIndex, PageSize, DescriptionFilterText);
DomainContext.Load(query, OnExamsLoaded, null);
El método de devolución de llamada a continuación, ejecuta la consulta para obtener los conteos. Si no se utiliza ningún filtro, obtenemos el recuento de todas las filas; si hay un filtro, obtenemos el recuento de las filas filtradas.
private void OnExamsLoaded(LoadOperation<ExamEntity> loadOperation)
{
if (loadOperation.Error != null)
{
//raise an event...
ErrorRaising(this, new ErrorEventArgs(loadOperation.Error));
}
else
{
Exams.MoveCurrentToFirst();
if (string.IsNullOrEmpty(DescriptionFilterText))
{
DomainContext.GetExamCount(OnCountCompleted, null);
}
else
{
DomainContext.GetFilteredExamCount(DescriptionFilterText, OnCountCompleted, null);
}
IsLoading = false;
}
}
También hay un método de devolución de llamada para el recuento:
void OnCountCompleted(InvokeOperation<int> op)
{
ItemCount = op.Value;
TotalItemCount = op.Value;
}
Con el conjunto ItemCount, el control DataPager lo recoge, y tenemos paginación con el filtrado y una consulta inteligente que devuelve sólo los registros de ¡se mostrará!
LINQ facilita la consulta con .Skip() y .Take(). Hacer esto con raw ADO.NET es más difícil. Aprendí cómo hacer esto desmontando una consulta generada por LINQ.
SELECT * FROM
(select ROW_NUMBER() OVER (ORDER BY Description) as rownum, *
FROM Exams as T0 WHERE T0.Description LIKE @description) as T1
WHERE T1.rownum between @first AND @last ORDER BY rownum
La cláusula de "seleccionar ROW_NUMBER() OVER (ORDER BY Descripción) como rownum" es la parte interesante, porque no muchas personas usan "OVER" todavía. Esta cláusula clasifica la tabla en Descripción antes de asignar números de fila, y el filtro también se aplica antes de asignar números de fila. Esto permite que SELECT externo filtre los números de fila, después de ordenar y filtrar.
¡Así que ahí está, paginación inteligente con filtrado, en RIA Services y Silverlight!
Cuando encuentro problemas como este con frameworks que se supone que hacen tareas comunes, en este caso paginación, es más fácil que te preocupes. Para usar RIA o no usar RIA esa es la pregunta ... – sipwiz
Bueno, esa es una pregunta abierta por ahora. RIA Services for Silverlight 3 y VS 2008 está prácticamente muerto; lo que está disponible ahora es la versión beta pública, que no se mejorará y se admitirá solo hasta diciembre. Entonces, los servicios de RIA para Silverlight 4 y VS 2010 son opciones. Está en el estado RC2 ahora; Lo verificaré tan pronto como llegue al estado de lanzamiento. FWIW, Brad Abrams dice que permita que la cuadrícula de datos de Silverlight haga la búsqueda, pero todavía existe el problema del filtrado personalizado, y eso es lo que realmente me mató inicialmente a los Servicios de RIA. Tenemos que ser capaces de filtrar en el servidor. –