jueves, 8 de noviembre de 2012

[Visual Studio] Base de Datos integradas al proyecto

 

Vamos a analizar una situación particular que se produce al integrar las bases de datos, ya sean Ms Access, Sql Compact, Sql Server, o cualquier otra que pueda integrarse al Visual Studio

Cuando se desarrollan aplicaciones de escritorio, WinForm o WPF y a estos proyectos se le agrega una db, puede que las actualizaciones de datos no impacten sobre el archivo que se visualiza en el “Solution Explorer”.

Nota: si bien el ejemplo del articulo estará basado en Sql Compact (.sdf) la solución planteada aplicaría a otras base de datos como ser Ms Access (.mdb, .accdb), Sql Server (.mdf), etc

 

Problema


Cuando un conectionstring se define usando el nombre de la db o |DataDirectory| para especificar la localización del archivo de base de datos, en ambos casos se hace referencia a la carpeta donde se encuentra ejecutándose el .exe

string connstring = "Data Source=|DataDirectory|Contactos.sdf;Persist Security Info=False;";

Al usar este tipo de connection string es bastante común ver desarrollos en donde la db se encuentra integrada al Visual Studio.

clip_image001

Si se está ejecutando desde el Visual Studio la carpeta, por defecto, donde compila y deja los archivos resultantes será el \bin\Debug del proyecto, es allí donde la aplicación espera que se encuentre la base de datos.

No hay que engañarse, los cambios que realicen actualización a la db no serán efectuadas sobre el archivo que se visualiza integrado al VS (el que se visualiza en la imagen anterior), sino que las modificaciones se realizaran sobre la copia que crea el Visual Studio en la carpeta \bin\Debug

clip_image003

Como se observa, el Visual Studio creo una copia de la db en la carpeta donde compila, es por eso que .exe y .mdb están juntos, es más cuando se detenga la ejecución y se inicie nuevamente una nueva copia será efectuada pisando los datos previos.

Por lo tanto, si luego de ejecutar la aplicación desde el VS, la aplicación realizo actualizaciones en los datos, al detenerla y realizar doble click en el archivo de base de datos que está integrado en el “Solution Explorer” para poder trabajarlo desde el “Server Explorer”, no se visualizara ningún cambio.

clip_image004

Al usar el “Show Table Data” no habrá cambios que visualizar

clip_image005

Sera necesario usar la opción

clip_image006

Para poder acceder a al db que se copió en el \bin\Debug y al hacer bloque click en esta y verla en el Server Explorer allí si estarán las actualizaciones realizaras en la ultima ejecución.

clip_image007

Nota: recuerden que al volver a ejecutar desde el Visual Studio la db que se encuentra en la carpeta \bin\Debug será reemplazada por una nueva copia

Esta situación solo se manifiesta si se ejecuta desde el Visual Studio, cuando se lleve el .exe a la pc del usuario esta situación no se presentara, la aplicación se ejecuta directamente sin intermediarios que realice la copia de la db a una carpeta de compilación (apunto a que no esta el Visual Studio en medio creando una carpeta donde ubicar los archivos resultantes necesario para la ejecución).

 

Solución


Si se quiere evitar esta situación y hacer uso de la misma db que esta integrada al proyecto, el primer paso será deshabilitar la copia que realiza el VS, para ello se debería ir a las propiedades del archivo

clip_image008

Y allí cambiar la opción a “Do not copy”

clip_image009

Y luego se deberá modificar el string de conexión indicando la ruta completa el archivo de la db, usar solo el nombre o |DataDirectory| ya no será valido (porque no se copiara el archivo a la carpeta de compilacion)

string connstring = "Data Source=C:\...\Contactos.sdf;Persist Security Info=False;";

 

Conclusión


Si bien esta característica que aporta el Visual Studio al realizar una copia automática del archivo de base de datos a la carpeta de compilación podría ser útil en algunas situaciones, (como ser aquellas donde se espera datos inicializados para realizar pruebas), pero hay otras donde no es útil, por eso existen opciones que se pueden cambiar para deshabilitar esta acción.

Al implementar la solución mencionada logramos referenciar la db que se encuentra integrada al proyecto.

[ADO.NET] Ms Access y arquitectura 64bit

 

Cuando desarrollamos bajo una plataforma con arquitectura de 64 bits se pueden presentar problema si la db usada se trata de Ms Access

Este problema se presenta porque el motor que usa para establecer la conexión desde código no provee compatibilidad con esta arquitectura

Para efectuar el artículo se hizo uso una PC con arquitectura 64bits

 

Base de datos .mdb


Para demostrar el problema se confecciono un ejemplo simple

clip_image001

Una base de datos Access 2000 integrada en proyecto la cual lista contactos en un grid

string connstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Contactos.mdb;User Id=admin;Password=;";

try
{
	using (OleDbConnection conn = new OleDbConnection(connstring))
	{
		conn.Open();

		string query = "SELECT * FROM Contactos";
		OleDbCommand cmd = new OleDbCommand(query, conn);
		OleDbDataAdapter da = new OleDbDataAdapter(cmd);
		DataTable dt = new DataTable();
		da.Fill(dt);

		dataGridView1.DataSource = dt;
	}
}
catch (Exception ex)
{
	MessageBox.Show(ex.Message);
}

El proveedor utilizado

Provider=Microsoft.Jet.OLEDB.4.0

Si se ejecuta sin realizar ningún otro cambio se obtendrá

The 'Microsoft.Jet.OLEDB.4.0' provider is not registered on the local machine.

clip_image003

Para que esto no suceda la solución es cambiar el Platform Target del proyecto, para esto solo se debe ir a la propiedades del proyecto

clip_image004

Y allí cambiar la opción mencionada a x86, con esto haremos que el .exe compile con compatibilidad a 32bits

clip_image006

Ahora si al ejecutar la aplicación funcionara sin problemas

clip_image007

 

Base de datos .accdb


Otra alternativa que podría evaluarse es la utilización de ACE.OLEDB como proveedor para trabajar con la db Ms Access, para ello seguramente se necesite instalar

Componente redistribuible del motor de base de datos de Microsoft Access 2010

Nota: si se tiene el Office 2010 (o superior) en la pc quizás no se requiera la instalación

Al cambiar de proveedor, ya no se usara Jet por lo que se define

Provider=Microsoft.ACE.OLEDB.12.0

clip_image009

Al ejecutar la aplicación funciona correctamente más allá de estar definida para compilar a 64bits

Nota: también se probó ACE.OLEDB con una base de datos .mdb (generada con Ms Access 2010 pero grabada con compatibilidad con Access 2000) pudiendo establecer la conexión correctamente sin que afectara la arquitectura 64bits

 

Conclusión


Si se quiere hacer uso de Jet como proveedor para establecer la conexión a los datos será necesario cambiar en el proyecto la plataforma a la cual se compila

Para evitar el problema se hará uso del proveedor ACE.OLEDB el cual proporciona compatibilidad con 64bit