martes, 12 de julio de 2011

SQL Server CE 4.0 NO ha venido para quedarse!

¿Te has parado a pensar como trabajar con SQL Server CE 4.0 en un proyecto en el que intervengan 2 o más programadores?

Digo esto porque si quieres tener tus bases de datos .sdf bajo control de código fuente, tienes un problema.

El primero es que el atributo de sólo lectura impide abrir una conexión contra la base de datos, así que cuando alguno de los programadores haga un check-in para desproteger el fichero y poder trabajar… a partir de ese momento el resto de programadores no podrán trabajar, así de sencillo y así de triste.

En nuestro caso, lo hemos resuelto no agregando este tipo de ficheros (.sdf) al control de código fuente, pero aun así, todavía tenemos un problema más.

Ahora sucede que queremos trabajar con una sola versión del fichero .sdf (sobre todo para que los cambios que realice uno de nosotros sean visibles para el resto), así que movemos el fichero a un carpeta compartida en la red. Pues bien, en tiempo de ejecución no hay ningún problema y nuestra cadena de conexión es similar a \\directorio\data.sdf y todo funciona correctamente. El problema está que por otro lado, Visual Studio ha decidido que no quiere abrir el fichero .sdf en el explorador de servidores (y como supondrás, esto significa que no podemos editar el fichero .sdf). He probado con el recurso compartido, con una unidad mapeada, con subst… pero nada.

Si quieres pruebas, hay van:

clip_image001

clip_image002

La conclusión es que trabajamos con un fichero .sdf en una ubicación de red pero cuando hay que realizar cambios en la estructura de tablas, el programador 1 dice “perdón, tengo que hacer cambios, así que me copia a local el fichero .sdf para poder abrirlo en Visual Studio, por favor, esperar a que termine…”, mientras el resto de programadores se fuman un cigarrito, se toman un refresco, etc. Cuando el programador 1 termina de hacer sus cambios vuelve a decir “Ya he terminado, sobreescribo el fichero .sdf de la red, ya podéis trabajar” y entonces el resto de programadores vuelven al tajo… Como verás, todo es muy científico y estamos muy contentos de trabajar con SQL Server CE 4.0 (es ironía, lo captas, ¿verdad?)

La solución propuesta no es mía y parece ser la norma, http://social.msdn.microsoft.com/Forums/en-SG/sqlce/thread/669f7bd3-d507-4e3f-b291-df8d5a51ae14

Yo, personalmente, me estoy empezando a hartar del tema y creo que exploraremos otras soluciones como MySql o cualquier otro gestor de base de datos serio, en vez de SQL Server CE 4.0. La experiencia de 2 proyectos ha sido bonita, educativa, pero la conclusión está clara… SQL Server CE 4.0 NO ha venido para quedarse!

Si quieres más motivos por los que SQL Server CE me saca de quicio, puedes leer estos otros post (que conste que lo he intentado, he defendido SQL Server CE 4.0 frente a colegas en el trabajo, he escrito posts, pero aun así…)

IsSys en SQL Server Compact 4.0 es peligroso!

NText en Sql Server Ce 4.0

Ficheros bloqueados de SQL Server CE 4.0 en proyecto ASP.NET

Soporte del diseñador de Entity Framework para SQL Server Compact Edition 4.0

Un saludo!

sábado, 9 de julio de 2011

Fábulas modernas (OFF-TOPIC)

Pues siendo sábado y tan prontito, un off-topic de fábulas o como queramos llamarlo. A mí me parecen muy interesantes y son los típicos cuentos que puedes contar en una reunión de amigos para partir la pana ;-)

12 monos y el aprendizaje social
http://www.kaosklub.com/12-monos-experimento-aprendizaje-social-adquirido/

Teoría de los cristales rotos
http://adaip.blogspot.com/2009/01/teoria-de-los-cristales-rotos.html

Un saludo!

viernes, 8 de julio de 2011

IsSys en SQL Server Compact 4.0 es peligroso!

Hoy hemos recibido una inesperada sorpresa cuando hemos visto que Dormammu también anida en la entrañas de SQL Server CE 4.0.

Si quieres comprobarlo tú mismo, basta con que crees una nueva base de datos SQL Server CE 4.0 y agregues un campo a una tabla con un campo cuyo nombre comience por el literal ‘IsSys’.

Por ejemplo, en nuestro caso, tenemos una tabla [Users] con un campo [IsSystem], pues bien, comienza la fiesta…

Con la herramienta oficial de Microsoft (digo oficial, pero realmente quiero decir la herramienta que un par de becarios desarrollaron en un par de días… con todo el respeto a los becarios) esta columna no se ve, está missing, bueno está missing sólo en algunos sitios…

·         Se ve cuando editamos el esquema de la tabla

·         NO se ve cuando mostramos datos de la tabla

·         NO se ve en la conexión de datos desde el explorador de servidores

clip_image002

clip_image003

clip_image004

Para complicarlo aún más, si en vez de “mostrar datos de la tabla”, creamos una nueva consulta y seleccionamos la tabla [Users], aparece lo siguiente (sigue perdida la columna):

clip_image005

Sin embargo, sí podemos escribir la siguiente consulta, pero el campo aparece como de sólo lectura… yo no entiendo nada…

clip_image006

Sin embargo, si utilizamos la herramienta SQL Server Compact Toolbox de ErikEJ, todo funciona correctamente ¿Por qué no contrata Microsoft a ErikEJ?

Finalmente, mi recomendación (imposición) está clara: No utilices el literal IsSys como comienzo en el nombre de un campo en una base de datos SQL Server CE 4.0.

Un saludo!

martes, 5 de julio de 2011

NuGet

Últimamente, mi universo .NET está creciendo con aportaciones de terceros, casi todas ellas open source. Por ejemplo, hay un componente de registro de errores llamando elmah que se a volver casi imprescindible en cualquier nuevo proyecto en el que embarque. De este modo, cada nuevo componente de terceros que incluyo en mis proyectos, conlleva como es lógico, cierto código en el fichero web.config, descargar los ensamblados correctos, configurarlo adecuadamente, etc.

Algunos de estos componentes son sencillos de configurar y se tarda más en explicarlo que en hacerlo, pero por otro lado, hay componentes que tienen dependencias terceros, demasiado código para incluir en el fichero web.config y no morir en el intento, etc.

Siendo así y para abstraernos de esta complejidad, podemos utilizar NuGet.

NuGet es, traducido literalmente de su página de codeplex (perdonar si mi traducción no es muy acertada) “un sistema libre de administración de paquetes enfocado a desarrolladores open-source para la plataforma .NET, con el propósito de simplificar el proceso de incorporar librerías de terceras partes en una aplicación .NET durante el desarrollo”.

Dicho de otro modo, “un sistema que nos permitirá incorporar en nuestras aplicaciones, componentes open-source de terceras partes, de forma automática y sin tener que conocer los entresijos de su instalación y configuración”.

Lo primero es instalar NuGet en nuestro Visual Studio, para ello podemos instalarlo desde el administrador de extensiones:

clip_image002

Una vez que la hemos instalado, tenemos las siguientes opciones disponibles en nuestra Visual Studio, desde el menú Herramientas:

clip_image004

La opción Package Manager Console nos abre una nueva ventana desde donde poder lanzar comandos para administrar la gestión de nuestros paquetes (tranquilo, que si no quieres lidiar con esta ventana, siempre podrás trabajar con una interfaz gráfica).

clip_image006

La opción Manage NuGet Packages es justamente la interfaz gráfica para los perezosos como yo que no quieren trabajar con la ventana de Package Manager Console. Por ejemplo, si buscamos Elmah en esta ventana, nos ofrece los siguientes resultados:

clip_image008

Como puedes ver, además de poder incorporar este componente a nuestro proyecto, el creador de Elmah se ha encargado de subir a NuGet distintas distribuciones de su proyecto para cubrir el mayor número de situaciones. Esta es otra de las ventajas de NuGet, que los creadores de librerías de terceros, crean sus propios paquetes (a veces varias como en nuestro ejemplo) y te ayudan a instalar su componente de la forma más transparente posible.

Por ejemplo, si seleccionamos la opción ELMAH on MS SQL Server Compact, podremos ver como también nos vamos a descargar de forma automática el runtime necesario para poder ejecutar MS SQL Server Compact, es decir, no tenemos que preocuparnos por esto, el creador del paquete decidió que había una dependencia de MS SQL Server Compact, y por ello se descargará junto a Elmah.

clip_image010

Después de haberlo instalado, la nueva situación de nuestra proyecto es la siguiente:

clip_image011

Se ha agregado una referencia a System.Data.SqlServerCe, se ha agregado un fichero marcador en App_Data (simplemente para informarnos de que creará el fichero elmah.sdf en este directorio), se ha agregado un fichero packages.config (que guarda la configuración de paquetes descargados e instalados desde NuGet en nuestra aplicación) y ha incluido el código necesario para ejecutar el componente elmah en nuestro fichero web.config (que te aseguro no son pocas líneas).

El fichero packages.config sería como sigue:

<?xml version="1.0" encoding="utf-8"?>

<packages>

  <package id="elmah.corelibrary" version="1.2" />

  <package id="elmah" version="1.2.0.1" />

  <package id="SqlServerCompact" version="4.0.8482.1" />

  <package id="elmah.sqlservercompact" version="1.2" />

</packages>


Ahora sólo queda probar nuestra aplicación creando una página sencilla que lance una excepción no manejada, con el propósito de que elmah la registre y ver que todo está funcionando correctamente.

Nuestro error no controlado:

clip_image013

Y nuestro módulo elmah funcionando sin apenas esfuerzo:

clip_image015

Pues llegados a este punto hay que reconocer, que instalar elmah sobre MS SQL Server Compact ha sido muy sencillo con NuGet.

Si ahora lo que quisiéramos es ver que paquetes tenemos instalados en nuestro proyecto, actualizarlos (que también está bien disponer de esta característica sin tener que visitar la página del autor) o incluso desinstalarlos, tendríamos que acceder de nuevo a la ventana de Manage NuGet Packages (que lo que hace es recuperar la información de packages.config).

clip_image017

En mi opinión, NuGet es una poderosa herramienta que viene a cubrir un hueco que tenía la plataforma .NET y que sí estaba cubierto en otras plataformas y lenguajes (sino me crees te puedes bajar el IDE eclipse para Java y ver cómo funciona maravillosamente su sistema de plug-ins).

Por último (y sólo con el propósito de al menos haberlo hecho una vez), vamos a ver como instalar este mismo paquete desde la consola de NuGet.

clip_image018

Intellisense, uoh!!

clip_image020

Pues la verdad es que casi se tarda menos desde la consola ;-)

Ahora imagina la cantidad de proyectos open-source de la comunidad .NET a tu alcance sólo con un par de clicks… pues tiene muy buena pinta

Un saludo!

lunes, 4 de julio de 2011

Saber la versión .NET Framework de un ensamblado


Un tip rápido ¿Cómo saber en qué versión del .NET Framework está compilado un ensamblado?
Aquí hay varias soluciones, pero lo cierto es que todas ellas la más sencilla es utilizar ildasm.exe (Desensamblador de IL).

clip_image001

Después, simplemente abrimos el ensamblado del que queremos saber su versión de .NET Framework y hacemos doble-click en MANIFEST y vemos la información que estábamos buscando:

clip_image003

Un saludo!.

viernes, 1 de julio de 2011

Crear nuevos elementos HTML con jQuery

Como cada día utilizo más jQuery y más código de cliente en detrimento de código de servidor, me he dado cuenta que una operación muy habitual es crear elementos HTML para su posterior inserción en algún lugar del árbol del documento. La verdad es que existen distintas formas de crear elementos HTML, ya sea a través de jQuery o bien a través de métodos estándar del DOM.

A continuación, te muestro algunas de las posibles formas que se me ocurren para crear un elemento div:

var div1 = document.createElement("div");

var div2 = $("<div></div>");

var div3 = $("<div />");

var div4 = $("<div>");


La primera forma utiliza el método estándar DOM, mientras que el resto utiliza jQuery. En realidad las llamadas de jQuery utilizan también internamente el método document.createElement. Yo, personalmente prefiero la opción "<div>" que es la más fácil tanto de escribir como de leer.

Seguramente sea Lo más óptimo es utilizar directamente document.createElement, pero prefiero que sea jQuery quién lidie con los métodos del navegador de turno, y yo intentar abstraerme de todo esto, que es justamente por eso por lo que estoy utilizando jQuery.

De hecho, si eres un enamorado de la performance y la optimización es una máxima para ti, puedes ver visitar el siguiente enlace, que tiene un test que compara todas estas opciones distintas de creación de elementos (aunque en mi caso no tengo previsto crear ningún bucle de 10.000 iteraciones creando div, pero bueno…)

Si quieres saber más sobre lo que dice “oficinalmente” jQuery sobre cómo se deben crear elementos al vuelo, puedes visitar http://api.jquery.com/jQuery/#jQuery2

Sea como sea, ahora ya hemos creado el elemento. En realidad esto sólo era el primer paso, después querremos darle contenido, establecer valores para ciertos atributos, etc. Pues bien, de nuevo aquí tenemos distintas opciones:

// Propiedad innerHTML

var div1 = $("<div class='Div2' style='color: White;'>Lorem ipsum</div>");

 

// Métodos jQuery

var div2 = $("<div/>");

div2.addClass("Div2").css("color", "White");

 

// Forma propuesta por jQuery

var div3 = $("<div />",

{

id: "Div3", //atributo directo, igual que si fuéramos con attr(“id”)

"class": "Div3", //class entre comillas porque es una palabra reservada en javascript

text: "Lorem ipsum", //text no es un atributo sino una propiedad de jQuery, por ejemplo: .text("Lorem ipsum")

css: //propiedad de jQuery

{

"font-weight": "bold", "color": "White"

},

click: function (e) { //evento de jQuery

alert("Hola mundo!");

}

});

 

En mi opinión, todas las formas son válidas, pero la tercera me gusta especialmente. De hecho, creo que es la única que merece una explicación porque tiene distintas opciones que deben ser asimiladas.

Por defecto, el nombre de las propiedades que pasamos en el objeto son nombres que utilizaríamos también con el método .attr(“Propiedad”) de jQuery. Así por ejemplo, id sería igual a .attr(“id”). Por otro lado, “class” va entre comillas porque es una palabra reservada del lenguaje, pero a excepción de esto se comportaría igualmente como .attr(“class”). Sin embargo, la propiedad text no es un atributo de un elemento DIV, es decir, no se puede escribir ni <div text=”Lorem ipsum”></div> ni tampoco .attr(“text”), pero funciona. Funciona porque jQuery reconoce text como una palabra especial que hace mención a la propiedad .text() de jQuery, y entonces lo que hemos escrito es equivalente a .text(“Lorem ipsum”). Esto mismo le pasa a css e incluso al manejador de evento para click. Como vemos, esta última opción es muy potente y permite configurar nuestro nuevo elemento de una forma más científica.

Por mi parte nada más, simplemente pensar que a partir de ahora sé un poco más sobre cómo crear elementos HTML con jQuery y no perecer en el intento.

Un saludo!

File Change Notification en ASP.NET

Si esto que te voy a contar nunca te ha pasado, estás de enhorabuena. En caso contrario espero que te sirva esta solución para no perder incontables horas navegando por Internet con cara de desahuciado.

El problema es que cuando eliminamos directorios por código, almacenados en la raíz de nuestra aplicación ASP.NET, el AppDomain asociado se reinicia. Esto significa que perderemos cualquier valor almacenado en Session (a no ser que la estés guardando en base de datos), en Cache, volverá a ejecutarse los eventos de Application en global.asax, etc.

Que te pase esto no es tan difícil. Por ejemplo en mi empresa estamos haciendo un programa que sube ficheros y los guardamos en App_Data. Por motivos que no son relevantes para este post, en un momento dado tenemos que eliminar subdirectorios que previamente hemos creado. Pues bien, en ese preciso instante se nos cae el chiringuito y la aplicación se reinicia.

Esto sucede desde ASP.NET 2.0 en adelante (curiosamente no sucede en ASP.NET 1.x) y es porque el componente FCN (File Change Notifications) está constantemente monitorizando cambios en la estructura de disco de nuestra aplicación para que en el caso de haya cambios se vuelva a compilar la aplicación automáticamente, siempre que sea necesario.

Que este componente esté vigilando la carpeta App_Data, lo cierto es que no le encuentro demasiado sentido. Es decir, está claro que agradezco que monitorice el directorio \bin, cambios en ficheros aspx, ascx, etc. ¿Pero en App_Data?

En cualquier caso, la única solución que hemos encontrado ha sido detener este proceso, es decir, decirle a ASP.NET que los cambios en mi aplicación no reinicien mi aplicación (cabe aclarar que el directorio \bin no se puede escapar a esta monitorización y seguirá activo y además casi lo agradezco, sino sería muy drástico).

El método es el siguiente y simplemente hay que llamarlo una única vez en el evento Application_Start (global.asax).

    Public Shared Sub StopFCN()

        Dim p As PropertyInfo = GetType(System.Web.HttpRuntime).GetProperty("FileChangesMonitor", BindingFlags.NonPublic Or BindingFlags.[Public] Or BindingFlags.[Static])

        Dim o As Object = p.GetValue(Nothing, Nothing)

        Dim f As FieldInfo = o.[GetType]().GetField("_dirMonSubdirs", BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.IgnoreCase)

        Dim monitor As Object = f.GetValue(o)

        Dim m As MethodInfo = monitor.[GetType]().GetMethod("StopMonitoring", BindingFlags.Instance Or BindingFlags.NonPublic)

        m.Invoke(monitor, New Object() {})

    End Sub


Si quieres ampliar más información al respecto, puedes visitar los siguientes enlaces:

http://blogs.msdn.com/b/toddca/archive/2005/12/01/499144.aspx

http://www.eggheadcafe.com/software/aspnet/30642781/workaround-for-fcndirectory-delete-bug.aspx

Un saludo!