MCTS 70-561: Consultando data

Construyendo comandos para consultas a base de datos, es un tema que siempre despierta interés y siempre esta un mejoramiento continuo. Muchos framework han tratado han tratado de sobreponerse, desde el antes usado SqlHelper o ahora la ultima versión del DAAB, pero la fin al cabo todas usan los objetos básicos de ADO.NET. En muchos casos cada casa de software siempre necesita acceso a datos personalizados, lo que motiva a la creación de su propio framework de acceso a datos, y nuevamente llegamos a usar las clases básicas de acceso a datos de ADO.NET. Con SqlCommand, podemos crear todo tipo de consultas para una base SQL-Server, desde crear nuestros propios queries, hasta llamar a StoreProcedures, y gracias a SqlParameter podemos parametrizar nuestras consultas, además que siempre vamos a encontrar soporte en ADO.NET para las nuevas features de SQL, por ejemplo en SQL 2005 se agrego una columna para el soporte de Xml, y en ADO.NET también se cree el tipo de dato SqlXml para soportar a esta nueva columna, los comandos también me permiten retornar valores. Y si están usando DataSets con SqlDataAdapter, pueden echarle un vistazo a SqlCommandBuilder, si usan listas para transmitir data entre las capas, no es necesario.

Hay muchos mitos en ADO.NET, de cual es la mejor DataReader vs DataSet, la serie de Carlos Walzer es excelente: Cazando mitos con ADO.NET.

Recuerden que en VS2005 (o superior), a evolucionado el DataAdatper, para crear una clase llamada TableAdatper, en aplicaciones web nunca los he usado, creo su mayor aplicación más va por el lado de Aplicaciones Windows.

Queries asíncronos, en ADO.NET 2.0, se mejor el soporte para este tipo de escenarios. En este artículo: Asynchronous Command Execution in ADO.NET 2.0, Pablo Castro nos comenta sobre los nuevos métodos que nos permitirán hacer tareas asíncronas con ADO.NET 2.0. En este ejemplo: Asynchronous command execution in .NET 2.0, podemos ver rápidamente como podemos usar los nuevos métodos de la clase SqlCommand, para el soporte de tareas asíncronas, pero notar en esta FAQ: ADO.NET 2.0 Asynchronous Command Execution (ASYNC) FAQ, que el uso de ASYNC=TRUE, en la cadena de conexión sólo para tareas asíncronas, más no para tareas comunes. Aquí otros artículos: Executing Database Commands Asynchronously with ADO.NET 2.0, y Asynchronous Data Access using Callback Model, también revisar los detalles detrás de los comandos asíncronos: Shared Memory Provider and Async Commands.

Hay algunos tipos que necesitan un cuidado especial, como por ejemplo el manejo de archivos, en file-system o en la base de datos?, esto básicamente dependerá de los requerimientos que se tenga, dependiendo de tu modelo, las tareas de backup de la información tendrá que ser de la base de datos, y de las carpetas de archivos, tendrás que tener doble manejo de seguridad, entre otras cosas a tener en cuenta. Aquí un ejemplo: Utilize ADO.NET and C# to work with BLOB data, mas de la discusión:file system vs Database images. Con SQL Server 2008, se propone otro modelo para almacenar archivos en la base de datos pero con un híbrido con FileSystem, leer el siguiente artículo: Getting Traction with SQL Server 2008 Filestream. Otro tipo de dato a manejar es el tipo de dato espacial que se liberará en SQL Server 2008: Demystifying Spatial Support in SQL Server 2008. Otra de las nuevas en SQL Server 2008, es el soporte del tipo tabla como parámetro, por su parte ADO.NET 3.5, ya soporta esta feature, aunque aún no se tenga la versión final de SQL Server 2008: SQL Server 2008: Table Value Parameters (TVP).

De LINQ, hay mucho en la red. Un artículo El proyecto LINQ, los post de ScottGu’s de LINQ, incluido una serie que tiene de LINQ to SQL. La presentación del gran Octavio Hernández, en el TechDays 2008: presentación(pptx) y demos. Y esta aproximación de LINQ To SQL en una Aplicación en Capas, teniendo en cuenta los comentarios que se han hecho.

Saludos,

LINQ to SQL y una Aplicacion en capas….

Vayamos directo al grano, vamos a tomar a AdventureWorks como ejemplo.

Veamos a Linq to SQL:

En la forma simple de usarlo agregamos un diagrama Linq to SQL Class, a nuestra aplicación:

 http://galeon.com/solocodigo/images/blog/2008/03Mar/22_Linq_Sql.jpg

Creamos una consulta simple y básica:

   1: static void Main(string[] args)
   2:     {
   3:  
   4:       dcAdventureWorksDataContext dbAW = 
   5:         new dcAdventureWorksDataContext();
   6:  
   7:       colGen.IEnumerable<Product> enumProd = 
   8:               from p in dbAW.Products
   9:               where p.Name.StartsWith("W")
  10:               select p;
  11:  
  12:       foreach (Product prod in enumProd.ToList<Product>())
  13:       {
  14:         Console.WriteLine("Prod: {0} -> {1}", 
  15:                   prod.Name, prod.ProductNumber);
  16:       }
  17:       Console.ReadLine();
  18:     }

Este query muestra todos la lista de productos cuyo nombre empiece con W.

Veamos la magia de Linq to SQL:

  • Para usar el diagrama que hemos agregado debemos usar una instancia del mismo.
  • Hay muchos ejemplos donde sólo se usa “var” para declarar a la variable que contendrá los resultados, y esto podría ser un útil para construir listas con nuevas columnas, por ejemplo columnas agregadas, claro eso en el select. Pero cuando yo agrego un diagrama LinqtoSQL, este también crea una clase por cada entidad en el diagrama:
   1: [Table(Name="Production.Product")]
   2: public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged
   3: {
  • Es por eso que cuando tu pones “p.”, te salen todas las columnas disponibles de la tabla mapeada, y no es que este consultado a la base de datos para saber que columnas tiene, si por ejemplo se agrega una columna a la tabla en la base de datos, tenemos que volver a mapear, o agregar la propiedad respectiva a la clase existente. Y es así que puede usar un IEnumerable<Product>, para almacenar los resultados, recuerden que la clase Product, yo no la he creado, a sido generada en la generación del diagrama.
  • Miren la condición que estamos agregando, creo que la principal ventaja, es que tenemos todo el soporte de .NET, para las condiciones y operaciones que necesitemos realizar en la consulta.
  • Como pueden ve,r fácilmente puede convertir IEnumerable<> a un List<>.
  • Pero que pasa en SQL?, miremos a SQL Profiler:
   1: exec sp_executesql N'SELECT [t0].[ProductID], [t0].[Name], [t0].[ProductNumber], 
   2:    [t0].[MakeFlag], [t0].[FinishedGoodsFlag], [t0].[Color], [t0].[SafetyStockLevel], 
   3:    [t0].[ReorderPoint], [t0].[StandardCost], [t0].[ListPrice], [t0].[Size], 
   4:    [t0].[SizeUnitMeasureCode], [t0].[WeightUnitMeasureCode], [t0].[Weight], 
   5:    [t0].[DaysToManufacture], [t0].[ProductLine], [t0].[Class], [t0].[Style], 
   6:    [t0].[ProductSubcategoryID], [t0].[ProductModelID], [t0].[SellStartDate], 
   7:    [t0].[SellEndDate], [t0].[DiscontinuedDate], [t0].[rowguid], [t0].[ModifiedDate]
   8: FROM [Production].[Product] AS [t0]
   9: WHERE [t0].[Name] LIKE @p0',N'@p0 nvarchar(2)',@p0=N'W%'
  • Primero que notamos?, que es un query parametrizado, es decir que si el usuario quiere hacer SQL Injection, sería algo como esto:
   1: exec sp_executesql N'SELECT [t0].[ProductID], [t0].[Name], [t0].[ProductNumber], 
   2:    [t0].[MakeFlag], .....
   3: FROM [Production].[Product] AS [t0]
   4: WHERE [t0].[Name] LIKE @p0',N'@p0 nvarchar(10)',@p0=N'W'' OR 1=1%'

Ya hablamos de lo bonito, pero….

  • Si tenemos una aplicación en capas, este modelo no nos ayudaría mucho. Ya que tenemos una capa especial para consulta de acceso a datos.
  • Y si quiero usar Linq to SQL, en capas?… a ver veamos

Ahora hagamos un custom Linq to SQL, para usarlo en una aplicación en Capas:

Digamos que yo cuento con mis entidades:

   1: public class miProducto
   2:  {
   3:  
   4:    private Int32 productIDField;
   5:    private String nameField;
   6:    private String productNumberField;
   7:    private Decimal listPriceField;
   8:  
   9:    public Int32 ProductID
  10:    {
  11:      get { return productIDField; }
  12:      set { productIDField = value; }
  13:    }    
  14:    public String Name
  15:    {
  16:      get { return nameField; }
  17:      set { nameField = value; }
  18:    }    
  19:    public String ProductNumber
  20:    {
  21:      get { return productNumberField; }
  22:      set { productNumberField = value; }
  23:    }    
  24:    public Decimal ListPrice
  25:    {
  26:      get { return listPriceField; }
  27:      set { listPriceField = value; }
  28:    }
  29:  }

A nuestra entidad tenemos que agregarle los siguientes atributos:

   1: [Table(Name = "Production.Product")]
   2:   public class miProducto
   3:   {
   4:  
   5:     private Int32 productIDField;
   6:     private String nameField;
   7:     private String productNumberField;
   8:     private Decimal listPriceField;
   9:  
  10:     [Column]
  11:     public Int32 ProductID
  12:     {
  13:       get { return productIDField; }
  14:       set { productIDField = value; }
  15:     }
  16:     [Column]
  17:     public String Name
  18:     {
  19:       get { return nameField; }
  20:       set { nameField = value; }
  21:     }
  22:     [Column]
  23:     public String ProductNumber
  24:     {
  25:       get { return productNumberField; }
  26:       set { productNumberField = value; }
  27:     }
  28:     [Column]
  29:     public Decimal ListPrice
  30:     {
  31:       get { return listPriceField; }
  32:       set { listPriceField = value; }
  33:     }
  34:   }

Con estos atributos estoy habilitando para que mi clase pueda ser usada con Linq to SQL, notar que en las propiedades de los atributos se puede determinar con que tabla voy a mapear, y podría determinar con que columna de la tabla voy a mapear una determinanda propiedad.

En la capa de acceso, mi clase sería así:

   1: public class ProductRepository
   2: {
   3:  
   4:   private DataContext dbAW;
   5:   public ProductRepository(String connectionString)
   6:   {
   7:     dbAW = new DataContext(connectionString);
   8:   }
   9:  
  10:   public IEnumerable<miProducto> getManyByNameStart(String start)
  11:   {
  12:     IEnumerable<miProducto> enumProd;   
  13:     
  14:       enumProd = from prod in dbAW.GetTable<miProducto>()
  15:                  where prod.Name.StartsWith(start)
  16:                  select prod;
  17:  
  18:       return enumProd;
  19:   }
  20: }

Notar que el connectionString lo estamos pasando de la capa que la llame, y es aquí donde iría los queries, Linq to SQL.

Y en la capa de negocios sería así:

   1: public class BLProduct
   2: {
   3:  
   4:   private ProductRepository repProduct;
   5:  
   6:   public BLProduct(String connectionString)
   7:   {
   8:     repProduct = new ProductRepository(connectionString);
   9:   }
  10:  
  11:   public List<miProducto> getManyByNameStart(String start)
  12:   {
  13:     return repProduct.getManyByNameStart(start).ToList<miProducto>();
  14:   }    
  15: }

Sólo un maquillado para la llamada de la capa de presentación.

Y por último el FrontEnd, lo podría usar así:

   1: static void Main(string[] args)
   2:  {
   3:  
   4:    String cnAW = 
   5:      ConfigurationManager.ConnectionStrings["dbAW"].ConnectionString;
   6:    BLProduct blProd = new BLProduct(cnAW);
   7:  
   8:    List<miProducto> lstProd = blProd.getManyByNameStart("L");
   9:    foreach (miProducto prod in lstProd)
  10:    {
  11:      Console.WriteLine("Prod: {0} -> {1}", 
  12:                prod.Name, prod.ProductNumber);
  13:    }
  14:  
  15:    Console.ReadLine();
  16:  }

Algunas conclusiones finales:

  • Esta es una de las formas como podría encajar Linq to SQL, en un modelo en capas. Si de todas maneras estas armando tus queries en la capa de acceso, pues Linq to SQL te puede caer a pelo de gato :D.
  • Ahora, si tienes un modelo donde sólo usas StoreProcedures, Linq to SQL, no va encajar bien en tu escenario.
  • Y noten que el dilema no sería Linq to SQL (en la capa de acceso a datos) vs. StoreProcedures, la verdadera discusión sería “Queries en ADO.NET o usar Store Procedures”…. por cierto aquí se armo una buena discusión: ventajas de usar Procedimientos Almacendos?.

Descargar ejemplo: Linq to SQL en una Aplicacion en Capas.

Nos vemos, y ya viene el post sobre Linq to Objects :D…

Saludos,

T34 [MixSessions08] – Construyendo una Aplicacion Ajax usando ASP.NET 3.5 y VS2008

En esta sesión: Building Great AJAX Applications from Scratch Using ASP.NET 3.5 and Visual Studio 2008, de Brad Abrams, vamos a ver como podemos aprovechar las features de VS2008 para mejorar el desarrollo de nuestras Aplicaciones Web.

En el blog de Brand Abrams, podemos encontrar el código de los ejemplos de esta sesión, en dos versiones: una completa para los que quieren ver la aplicación funcionando, y una versión Starter, para los que quieren hacer la aplicación en modo de HOLs, en el post de Brad, encontrarán los pasos a modo de HOLs, para completar la aplicación, por cierto se nota, que las diapositivas han sido hechas con mucha dedicación, y es un excelente estilo xD!, creo que también voy a comenzar a aplicarlo :D.

Las primeras partes, de las demo les va resultar familiar, si ya han revisado este post de ScottGu, creo que es un ejemplo práctico de mostrar el manejo de CSS, el control ListView, y Linq, por eso también lo use como modelo para las demos, pero con otra aplicación de ejemplo :D.

En la siguientes demos muestra como hacer AJAX del lado del servidor, con ASP.NET AJAX, y de AJAX del lado del cliente llamando desde JavaScript a servicios WCF-Ajax, como depurar el JavaScript, y por último cierra con el uso del AJAXControlToolkit, y como ahora podemos usarlos fácilmente, también muestra como optimizar el uso de los controles de ACT.

Ahora algo que debe quedar claro, es si bien los ejemplos vistos son buenos y nos muestran como podemos explotar las features de VS2008, tampoco quiere decir que todo esto lo vamos aplicar a todos los proyectos que estemos desarrollando:

  • Por ejemplo las mejoras de CSS que ahora tiene VS2008, no nos hará mejores designers, ni tampoco crearemos diseños espectaculares sin esfuerzo, Visual Studio es una herramienta de desarrollo hasta el momento, y si quieres hacer diseños avanzados de páginas va costar un poco más, existen herramientas como Dreamweaver, y ahora, Expression Web, que le quiere hacer la competencia, que son herramientas de diseños Webs; pero entonces surge la pregunta: ¿De qué me sirve este manejo de CSS mejorados en VS2008?. Pues por ejemplo si en tu proyecto no tienen presupuesto para un designer profesional, o te dan la tarea a ti, en mi caso es obvio que no voy hacer un buen diseño, no se ni por donde empezar, pues lo único que queda es tomar la plantilla de otro sitio web y reutilizarlo, y es ahí donde estas nuevas features para el manejo de CSS me van ayudar, siendo un no designer, hacer cambios o agregar nuevas estilos con mucha más facilidad. Por ahí creo que esta orientando, no que ahora te va convertir en un designer, ni que vas hacer diseños espectaculares con VS2008, siendo un no designer.
  • El uso de Linq to SQL, si tenemos una aplicación en capas es obvio que esto no cuadra, salvo que valla en la capa de acceso a datos, pero no se si sea lo correcto, además que si ya tenemos un modelo para la capa de acceso a datos, y lo vamos a cambiar debe ser por algo que tenga similar o mejor comportamiento en rendimiento, seguridad, manejo de excepciones, entre otros. Donde si veo útil el uso de Linq en este momento, es usando Linq to Objects, es más esto ya lo estoy implementando. Imaginen que tienen subir data a su servidor de base de datos provenientes de archivos excel, bueno primero hay que llenar la data en una List<Products>, pero además de hacer el upload tengo que validar, que todos los productos tengan código, que el código no se repita, entre otras, aquí el uso de Linq para estas tareas es excelente.
  • El uso de JavaScript con servicios WCF-Ajax, debe ser casos puntuales donde se necesita enriquecer y aumentar la usabilidad y funcionalidad de la aplicación, tampoco lo voy aplicar a todo. Recuerden con este modelo AJAX del lado del cliente, lo que se intercambia con el servicio sólo es datos, más no presentación, y esto hay que hacerlo en JavaScript, en este caso el esfuerzo ahora se va centrar también en modificar el diseño desde JavaScript, el uso ya depende de cada escenario.

P.D.: Disfruten de la sesión :).

Saludos,

MCTS 70-562: Consumiendo y creando controles de servidor

Aprender a manejar los controles de datos, son básicos, los que se liberaron con ASP.NET 2.0, tienen muchas opciones para personalizarlos: GridView, DetailsView, y FormsView.

  • El control DataGrid, creo que se quedo en VS2003, y el control GridView tiene mucho más poder. Y si usas VS2005 o superior, ni mires al DataGrid :D, sólo es bueno saber que fue el control principal para mostrar data en VS2003, y nada más :).
  • El control DataList, permite mostrar información en lista, también editar, haciendo el uso de plantillas. Con la propiedad RepeatLayout, puedes escoger si muestra la lista en estructura tabla, o en un flujo continuo. A través de los templates tu puedes decir como se muestra la cabecera, los items, los items alternativos (eso para tener la lista en dos colores, para una mejor identificación de las filas).
  • El control Repeater, te muestra el html como tu le dices, no tiene funcionalidades built-in como el DataList, pero te permite personalizar todo el html que se muestra al usuario. En un prueba de performance que alguna vez vi en un libro, en el orden de request/seg (quien tiene más repuestas), se lo lleva Repeater, donde el html mostrado es más limpio, y le sigue el DataList, y por el último el DataGrid. Se puede decir que las funcionalidades built-in, están relacionados inversamente con el render óptimo de html.
  • GridView, y aquí empiezan los nuevos controles de Data liberados con ASP.NET 2.0. Este control tiene muchas funcionalidades built-in, puedes hacer paginación con un click, ordenamiento, tiene nuevos soportes para columnas, puedes extender el control. Para muestra de datos donde no se requiere un render personalizado del html, este control es ideal para mostrar listas. Soporta los controls XDataSource. Digamos que este control es la evolución del DataGrid. Con este control, podemos listar, editar, y eliminar registros, y que pasa si queremos ingresar un registro?, revisar el siguiente control.
  • DetailsView, te permite mostrar un registro a la vez, pero te permite ingresar nuevos registros. Este ya no lo uso mucho, prefiero usar el control FormView, cuando tengo que hacer un mantenimiento. FormView vs. Details View.
  • FormView, que puedo decir?, para mi este (usándolo con un ObjectDataSource apuntando a una clase que tiene un método insertar, actualizar, eliminar y traer uno) control es el control de mantenimiento, aún veo mucha gente que no lo usa. Y a mi parecer es porque que piensan que no se puede personalizar, a este control le puedes personalizar todo, sólo usar la plantilla de insertar, sólo la editar, las dos. Puedes personalizar los botones para las operaciones de CRUD, o simplemente puedes llamarlos de controles externos programáticamente, puedes agregar valores (en el evento inserting, y updating) que por ejemplo estén fuera del control FormView, puedes manejar errores (en el evento inserted, updated, deleted), y todo tipo de mantenimiento puedes hacer con este control, puedes usarlo con ASP.NET AJAX, nuevamente, este es “el control de mantenimiento”. Ya no, al objPerson.Name = txtNombre.Text, o algo txtNombre.Text = objPerson.Name, este control lo hace todo, verdaderamente que te quita un gran trabajo de encima, sobre todo cuando tienes mantenimientos de objetos con 20 a 30 campos. Definitivamente tengo que hacer un post, para que me crean :D.
  • ListView, para mi este control es un híbrido entre el GridView-DataList-Repeater, es como el Repeater porque muestra un html limpio, tu personalizas como quieres que se muestre cada parte del html, es como el control DataList por que permite editar información, y es como el GridView porque soporta la paginación, con el Repeater tu tenías que crear la paginación, ahora el ListView junto con el control DataPager, te muestran los resultados paginados. Buena combinación: tu objectDataSource apuntando a tu clase con dos métodos TraerTodos paginado, y el método ContarFilas, para una paginación personalizada y optimizada con el ObjectDataSource, + el control ListView donde tu le dices como se muestra el html, + el control DataPager, para el soporte de paginación, definitivamente una buena combinación. DataList vs Listview, por cierto un plus, el ListView es el único control de Lista que soporta la inserción como template, con los otros hay que hacer alguna marcianada para lograr esto.

De creación de controles ya hemos hablando, de los controles de validación también, por cierto no confundir validación con seguridad, y los otros controles… pues bueno… son los otros controles :D.

P.D.: Creo que deberían dedicarle buen tiempo a los controles de Data, de verdad que todo lo necesita una aplicación, validación, manejo de errores, personalización de funcionalidad, de presentación, todo se puede hacer. Recursos útiles: http://www.asp.net/learn/.

Saludos,

MCTS 70-561: Conexión a una fuente de datos

Revisando este tema recién me entero de la existencia de ConnectionStringBuilder, pues recontra útil, te evitas de problemas de que pusiste mal el nombre de “DataSource”, en lugar de “Data Source”, ya no tienes que buscar en google que opciones tiene la cadena de conexión todas están como propiedades de la clase, y algo más importante evita el injection dentro del connectionString, definitivamente una buena manera de crear un ConnectionString.

ConfigurationManager, recuerden que con esta clase podemos recuperar Settings de un archivo *.config, connectionStrings, y además una sección en particular, que es útil para editar alguna feature del archivo *.config en tiempo de ejecución. Recuerden que para aplicaciones web se recomienda el uso de WebConfigurationManager, al crear un instalador verán como es útil poder modificar dinámicamente el archivo web.config. ConfigurationManager vs WebConfigurationManager?.

No se olviden de encriptar su cadena de conexión, al hacer deployment de su aplicación Web. Usando la herramienta aspnet_regiis.exe -pe, para encriptar, y el comando aspnet_regiis.exe -pd, para desencriptar. Rápido y útil, hasta podemos tener nuestro script con este comando, cada vez que hagamos deployment. Por cierto también se puede hacer programáticamente, pero habría que darle permisos la usuario para modificar el archivo web.config. Un detalle interesante es al abrir el Snap-in de ASP.NET IIS 6.0, podemos ver y editar claramente la cadena aunque este  encriptada, en IIS 7, no soporta la visualización de la cadena de conexión encriptada, no se si quitaron este soporte, o hay que hacer algo más para ver la cadena de conexión encriptada en IIS 7.

Revisar MARS, sobre todo cuando queremos usar dos SqlDataReader bajo una misma conexión, antes no se podía usar la misma conexión para dos SqlDataReader, pero con MARS si. Por ejemplo queremos usar un SqlDataReader para recorrer un conjunto de resultados, y dentro del bucle, hacer un update, este escenario puede ser comparable con lo se hace en SQL usando cursores. Recuerden que nunca hay que explotar un feature, y hay que buscarle el escenario, revisar el excelente análisis que hace Dino Esposito, en este artículo vemos MARS en el SQL Profiler, también revisar: Introducing MARS (2), y MARS – Transactions and Debugging. Recuerden hacer el uso de Using, para un mejor manejo del pool de conexiones.

Recuerden que además de los provider soportados por ADO.NET 2.0 por defecto, OleDb, Obdc, SqlClient, y OracleClient, muchos de los providers han desarrollado su propio driver: MySql Connector/Net 5.2 (integración con VS2008), .Net data provider for Postgresql, Oracle Data Provider for .NET, DB2 for .NET, entre otros. Recuerden siempre visitar la web de los providers, para revisar si hubo alguna actualización. Tip: Algunos de los providers MySql y Oracle (hasta donde se), soportan el modelo de providers de ASP.NET 2.0, como membership y roles.

Revisar el Namespace System.Data.Common, con este podemos crear conexiones independientes del proveedor, es decir por ejemplo si queremos desplegar una aplicación que use Sql o Oracle, dependiendo de la elección del usuario, con estas clases podemos hacerlo, revisar este artículo: Writing Provider-Independent Data Access Code with ADO.NET 2.0. Aunque esto tiene sus desventajas, por ejemplo lo genérico es menos especializado, en cambio un SqlClient o un OracleClient, va aprovechar mejor determinas features de un proveedor en especifico. Habría que poner en balanza, si conviene desarrollar dos módulos en la capa de acceso a datos uno para Sql y otro para Oracle, o hacer uno genérico, claro esto dependiendo de tiempo/costo/rendimiento/performance/conocimiento.

Y para terminar no se olviden de manejar de forma adecuada los errores con las base de datos en nuestra aplicación, mostrando al usuario un mensaje amigable, y registrando para interno (logging) el código del error para saber que es lo realmente paso. Manejos de errores con SQL: Design Elements Part 3: Error Handling, Handling SQL Server Errors in Nested Procedures, y no se olviden que en una aplicación los controles de data nos permiten manejar los errores y mostrar mensajes amigables: FormView.ItemUpdated Event, el ForView, DetailsView, GridView, y ahora imagino que también el ListView, en los eventos de actualización, inserción y borrado, permiten manejar y tratar las excepciones, ah los controles XDataSource también permiten el manejo de excepciones, en todos los querys que estos hacen. Ah y por cierto cuando manejan errores en SQL, se han podido dar cuenta que pueden personalizar los mensajes de error conociendo los códigos, pues aquí les dejo una lista:

Trujillo @ Nos vemos y es todo por hoy

Saludos,

SplendidCRM, Open Source CRM

SplendidCRM, es sitio Web CRM Open Source, esta escrito con C# 2.0.

Quizás no estemos muy familiarizados con el tema de CRM, esta es una buena oportunidad para ello, pero sobre todo es un buena oportunidad para aprender de la arquitectura y el diseño de esta aplicación. Podemos aprender desde la aplicación hasta la base de datos, como manejan el tema de búsquedas, links rápidos, manejo de ayuda, importar/exportar contacto, hay un montón que aprender. Como siempre digo, y como me lo recalco mi jefe anterior, no se rompan la cabeza con una determina feature, si otros ya lo hicieron hay que aprender de ellos.

Maneja: Calendario, Actividades, Contactos, Cuentas, Leads, Oportunidades, Casos, Bug Tracker, Documentos, y Emails, e imagino que se le pueden agregar más cosas.

Fuente: SplendidCRM 2.0 Free, Open Source, CRM.

Saludos,

MCPD 70-547: Traducir especificaciones para el desarrollador

El Jefe dice: “Y cuando esta la aplicación funcionando, cuando la vamos a poder usar?”. Y tu dices: “Estamos terminando las especificaciones de la Aplicación”, y te replican: “Lo mismo me dijiste hace dos meses”.

Vamos hablar de proyectos chicos que se deben terminar en menos de un año, con poco recurso humano. Una de las cosas por las cuales te van a contratar para hacer una aplicación es por que la empresa ha visto que ya no pueden más sin un sistema, o por que son precavidos y dentro de su plan estratégico de este año esta automatizar sus procesos usando alguna aplicación, o por que necesitan urgente una aplicación, ya que tiene una aplicación con algunos muertitos que eliminar. Sería ideal trabajar sin presión, pero normalmente necesitan las aplicaciones en dos modos: Urgentes, o SuperExtremadamenteUrgentes.

Estimación es algo que no me atrevería hacer aún, por que, aún el mundo no esta muy de acuerdo en esto (Ref1 y Ref2). Pero hombre, alguna respuesta tienes que dar. A mi parecer lo que se puede hacer es tomar el modelo de Scrum, y tener releases de la aplicación cada 3 meses. Con esto podrías tener hecha la aplicación en la versión 3.2 o 3.3, dependiendo. Y hay algo muy importante de aplicar esto, es que el Cliente va poder recuperar su inversión, si no hay mucho muertito en la aplicación, a fines del tercer mes. De alguna manera va sentir que lo que esta pagando esta dando resultados. Y todos contentos, el Cliente puede empezar a usar la aplicación, y nosotros nos liberamos de presión. Pero si hemos planificado hacer toda la especificación al inicio, y nos tardamos mas de dos meses, vamos a tener tal presión que puede hacer tambalear al proyecto. Con respecto a este tipo de proyectos donde se necesita un desarrollo rápido, usar un enfoque ágil es lo mas adecuado. Ya cada uno de acuerdo a su modelo de negocio, tendría que determinar que features salen en el primero release, y cuales no.

Este capítulo habla sobre las especificaciones, pero comente al inicio de esta serie, a parte de solo hablar de los temas, voy a dejar un poco de mi poca experiencia y como he estado implementándolos, bien o mal, pero implementándolos :). Y en cuanto a las especificaciones hablan de como crear un modelo lógico usando ORM, también habla sobre crear nuestra aplicación en Capas, que por cierto a mi parecer si se hace bien, hace muy fácil el mantenimiento de una aplicación, a parte que le da mucho orden para revisarla. El otro día vi una aplicación sin capas, que para que les cuento, por eso creo que me apure en tener un release, para no tener que darle mantenimiento a esa aplicación :D, pero ese es otro tema. Otra especificación son los modelos físicos de una aplicación: Crear un diagrama de componentes, diagrama de clases, de secuencia, y de actividades. Como he comentado en otros post, creo que el uso de diagramas debería ser de acuerdo al requerimiento y su complejidad del mismo. Por ejemplo, si estas contra el tiempo y tienes 4 mantenimientos de tablas estilo tipo o categoría, hacer todos los diagramas de UML por cada uno, donde sólo cambia el nombre del objeto y el resto es CRUD, como que no lo veo muy productivo, en todo caso se podría hacer uno genérico.

Ojo los requerimientos tienes que hacerlo si o sí, tampoco vas codificar desde el inicio del proyecto sin ningún requerimiento. Pero lo más importante que hacer un requerimiento, es que el Cliente apruebe estos requerimientos, así cuando se tenga el primer release, no habrá sorpresitas en lo que se dijo o no se dijo, y no tendrás que hacer todo dos veces :).

Saludos,

Browse with: "Safari 3.1" en Visual Studio

No es una novedad hacer esto, pero por ahí alguien que no tenía este dato. Aprovechar también para comentar que ya podemos hacer “Browser with” en VS200X, con una versión final de Safari.

El soporte de un navegador es algo que debería estar definido al inicio del desarrollo de la aplicación, aunque lo ideal sería hacerlo con estándares y que se vea en todos de la misma forma.

Pero por ejemplo si te dicen que tu aplicación se va ver Internet Explorer y Firefox, pero al final también te dicen que va tener que ser visto en Opera o Safari, como te puede descuadrar. Sobre todo si no eres designer, imagino que para designers profesionales que desarrollan usando estándares no debe ser algo difícil, el problema viene si somos developers y hemos logrando un diseño bonito a guerra, que funcione en IE y en Firefox, y será otra guerra hacerlo que se vea bien en otro navegador.

Y si eres developer y no quieres guerrear mucho diseñando, pues bájate un template: templates for ASP.NET, y si a tu jefe no le gusta uno de esos diseños, lo invitas cordialmente a contratar a un designer xD!

Saludos,

LDLS: .NET y mas [2008mar17]

ASP.NET, Web

Silverlight

Visual Studio 2008 y .Net 3.5

Varios

Humor

ASP.NET 3.5 y el CLR 2.0…

Primero vamos hacer un pequeño cuadrito para explicar que onda con la versión del CLR.

VS2005                   ->  VB8.0/C#2.0 – CLR 2.0 (llamado .Net Framework 2.0)
VS2005 Extensions ->  VB8.0/C#2.0 – CLR 2.0 + {WCF + WPF + WF + CS } (llamado .Net Framework 3.0)

Hasta aquí, se conocía a ASP.NET como ASP.NET 2.0. Pero tras la liberación de VS2008, como anda esto?

VS 2008                  -> VB9.0/C#3.0 – CLR 2.0 {ahora llamado .Net Framework 3.5}

A partir de VS2008, a ASP.NET se le conoce como ASP.NET 3.5. Revisando el cuadrito, podemos concluir que las aplicaciones creadas bajo .NetFx 3.5, corren bajo el CLR 2.0, y por ende ASP.NET 3.5 también corre bajo el CLR 2.0. Es por eso que cuando nosotros queremos publicar una aplicación ASP.NET 3.5 en nuestro servidor con IIS 6.0 (que tiene instalando el .Net Framework 3.5), no tenemos la opción para escoger una versión de ASP.NET 3.5, sólo ASP.NET 1.1 y ASP.NET 2.0:

De igual manera todas las aplicaciones Web Compiladas la vamos encontrar en la carpeta: “C:WindowsMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET Files”.

Si quieren publicar una aplicación ASP.NET 3.5, no busquen la versión ASP.NET 3.5 en el IIS, recuerden que ASP.NET 3.5 corre sobre el CLR 2.0.

Es más podríamos decir que ASP.NET 3.5 = ASP.NET 2.0 + Linq + ASP.NET AJAX + BCL3.5. Por eso no esta mal si revisamos tutoriales de ASP.NET 2.0, si aún no hay mucho sobre ASP.NET 3.5, todo lo que aprendamos con ASP.NET 2.0 lo podremos aplicar para desarrollar una web bajo ASP.NET 3.5, como ya lo comentamos en un anterior post, y como dije en ese post, si ustedes pueden escoger no usen VS2003.

Y si ustedes saben ASP.NET 2.0 + Linq + ASP.NET AJAX, entonces también pueden decir que saben ASP.NET 3.5.

Algunos post sobre el tema:

Saludos,