Pruebas de binding, y estudio de filtrado
Después de un nutrido banco de pruebas realizado por Caña, nada menos que 10 pruebas, parece claro que la implementación de nuestra colección de negocio debe ser una BindingList. No directamente, sino una colección que herede de ella, para contar con su funcionalidad. En resumen, las pruebas realizadas consistieron en enlazar (FListado o FObjeto) -> [BindingSource] -> [List o BindingList] -> objeto(s) y las conclusiones son:
- No importa de qué forma combinemos un BindingSource con un List
, la inclusión de nuevos objetos en la colección no se refresca en el interfaz de usuario. Para esto, es necesario que la colección implemente IBindingList. - Si conectamos el interfaz de usuario a la colección directamente, esta debe ser IBindingList para refrescarse, en otro caso (que sea una List) el interfaz sólo se refresca manualmente.
- En cambio, al conectar directamente el BindingSource al objeto omitiendo la colección, sí se refresca todo correctamente, por lo que es un método válido para las Fichas. No lo consideramos para listados, ya que el BindingSource es un componente de interfaz. ¿La colección de negocio podría heredar de BindingSource en lugar de hacerlo de BindingList? No es este el planteamiento de la librería .NET ni de los que diseñaron el enlace a datos.
- El bind ofrece el interfaz para hacerlo (eso sí, muy sencillo, tipo cláusula WHERE de SQL), pero no ofrece su implementación, sino que confía en la posible implementación del DataSource del que bebe. En este caso dicho DataSource es nuestra colección, que en su diseño actual (heredando de BindingList) no ofrece esta funcionalidad. Si no encontramos clases en la librería que nos permitan realizar fácilmente esta funcionalidad, es muy posible que esta opción sea descartada.
- Pero aún en el caso de no implementarla, la colección ofrecerá la funcionalidad. ¿Qué quiero decir? Que si la colección no sabe filtrarse, tendrá que buscar otro sistema: realizar el filtro directamente sobre la base de datos, con el sobrecoste de rendimiento que supone, pero de forma transparente para el objeto llamante. Esto nos situaría en igualdad de rendimiento con la implementación actual de Motorwin en VB6, donde todo filtro es convertido en SQL y resuelto por la BD, aunque sea un subconjunto de los datos que antes estábamos mostrando. No nos gustaría tirar por este camino, así que pensamos en una tercera opción.
- Utilizar la funcionalidad de filtros que ofrece ADO.NET. No olvidemos que ahí está todo hecho (recordar el antiguo modelo de cursor del lado de cliente de ADO 2.0), aunque trabajando con una representación concreta de la base de datos, por lo que no nos sirve para tratar directamente con nuestros objetos de negocio. Así que ¿cómo podemos aprovechar esta funcionalidad? En lugar de llegar a repetir la consulta a la base de datos, ya en la DAL, si somos capaces de detectar que el nuevo filtro siempre será un subconjunto del anterior, podemos aplicar el filtro al DataSet (posiblemente usando un DataView) y refrescar la colección, quizá manteniendo 2 colecciones paralelas, una de objetos del filtro actual y otra con todos los objetos originalmente cargados. Este es más costoso de implementar, como vemos, pero por la mejora en el rendimiento es muy deseable. Y no debemos olvidar que el filtro sobre un filtro anterior para ir afinando una búsqueda es de lo más habitual que hace un usuario sobre un listado, por lo que cuanto más eficiente sea, mejor.
