Je travaille actuellement sur un projet de solution web qui doit être en mesure de tourner sur 3 types de bases de données, à savoir SQLServer, MySQL et SQL Compact Edition. Enterprise Library tombe sous le sens avec ce type d’architecture. Pour SQL Server, pas de problème, c’est en natif, tout comme SQL Compact Edition qui nécessite néanmoins l’installation de son Runtime. Pour MySQL, le EntLib Contrib arrive a point nommé et permet d’utiliser le provider ADO.Net officiel de MySQL avec Enterprise Library.
Après avoir résolu les questions de requêtes différentes en fonction de la base cible par une architecture adéquate, me voila lancé dans mes tests. Parfait ! Tout roule…. Jusqu’au déploiement !
1. Le déploiement
J’utilise un Virtual PC sous Vista Home Edition pour faire mon test. La sécurité renforcée de Vista me permet de me mettre dans la situation la plus critique.
Déployant mon application Web sur le poste type de Madame Michu, je m’aperçois vite qu’il me manque un certain nombre de DLL :
- System.Web.Extensions, pour les fonctions Ajax. Cette DLL n’a plus besoin d’être dans le GAC. A mettre dans mon Bin et tout va bien.
- System.Data.SqlServerCe.dll et ces autres dlls. Rien a faire. Mêmes dans le bin, la connexion à ma base SQL Server Compact Edition ne marche pas.
2. Le cas d’étude
Je décide donc de repartir de zéro sur un cas d’étude simple avec 4 alternatives pour accéder à ma base SQL Server Compact Edition :
- Utilisation d’Enterprise Library
- L’utilisation directe de l’objet SqlCeConnection
- L’utilisation du DbProviderFactory, comme Enterprise Library
- L’utilisation d’un DbConnection avec un SQlCeConnection
Pour information, je rappelle que le runtime SQLServer Compact Edition n’est pas et ne doit pas être installé sur mon poste cible.
2.1. La mise en œuvre
2.1.1. Les informations de base
Mon Web.Config contient les données de connexion ainsi que les nœuds relatifs à Enterprise Library.
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</configSections>
<connectionStrings>
<add name="ConnString" connectionString="Data Source ='c:\inetpub\wwwroot\SqlCeDemo\test.sdf';Persist Security Info=False; Password ='test'"
providerName="System.Data.SqlServerCe" />
</connectionStrings>
Mon code de test dispose de la requête et de l’instruction qui permet d’utiliser SQLCe dans le cadre d’une solution ASP.Net
AppDomain.CurrentDomain.SetData("SQLServerCompactEditionUnderWebHosting", true);
string sqlCommand = "SELECT first_name FROM users WHERE user_name = 'elgee'";
2.1.2. Utilisation d’Enterprise Library
Tout simple, je donne ma connectionString à ma Database et je lui affecte une requête. Le retour est placé dans un TextBox.
#region AVEC ENTERPRISE LIBRARY 3.1
Database db;
try
{
db = DatabaseFactory.CreateDatabase("ConnString");
using(DbCommand cmd = db.GetSqlStringCommand(sqlCommand))
{
TextBox1.Text = (string)db.ExecuteScalar(cmd);
}
}
catch(Exception ex)
{
Label1.Text = ex.Message;
}
finally
{
db = null;
}
#endregion
2.1.3. Utilisation de l’object SqlCeConnection
Disponible via l’assembly System.Data.SqlServerCe, je dispose d’objets typés SqlCe. Même travail.
#region AVEC L'OBJET SQLCECONNECTION
SqlCeConnection con = new SqlCeConnection();
try
{
con.ConnectionString = ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
con.Open();
using (SqlCeCommand cmd = new SqlCeCommand(sqlCommand, con))
{
TextBox2.Text = (string)cmd.ExecuteScalar();
}
}
catch(Exception ex)
{
Label2.Text = ex.Message;
}
finally
{
con.Close();
con = null;
}
#endregion
2.1.4. Utilisation d’un Provider Factory, comme le fait Enterprise Library
Le DbProviderFactory permet de définir le provider de notre DbConnection.
#region AVEC UN PROVIDER FACTORY, Comme enterprise Library
DbProviderFactory dataFactory;
DataTable dt = new DataTable();
DbCommand cmd3;
try
{
dataFactory = DbProviderFactories.GetFactory("System.Data.SqlserverCe");
using (DbConnection conn = dataFactory.CreateConnection())
{
conn.ConnectionString = ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
conn.Open();
cmd3 = conn.CreateCommand();
cmd3.CommandText = sqlCommand;
TextBox3.Text = (string)cmd3.ExecuteScalar();
}
}
catch (Exception ex)
{
Label3.Text = ex.Message;
}
finally
{
dt = null;
cmd3 = null;
dataFactory = null;
}
#endregion
2.1.5. Un mix entre mon SqlCeConnection et mon DbConnection
J’initialise mon DbConnection avec un SqlCeConnection. Rien de plus simple :
#region UN DBConnection initialisé avec un SQLCeConnection
DbConnection c = new SqlCeConnection();
DbCommand cmd2;
try
{
c.ConnectionString = ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
c.Open();
cmd2 = c.CreateCommand();
cmd2.CommandText = sqlCommand;
TextBox4.Text = (string)cmd2.ExecuteScalar();
}
catch (Exception ex)
{
Label4.Text = ex.Message;
}
finally
{
cmd2 = null;
if (c != null)
c.Close();
c = null;
}
#endregion
2.2. Le résultat :

Avec le runtime SqlServer Compact Edition non installé sur mon poste client, mon application ne fonctionne pas avec Enterprise Library et le DbProviderFactory. Logique puisqu’Enterprise Library utilise lui aussi le DbProviderFactory.
La raison est simple. Il suffit d’écrire ces quelques lignes pour comprendre :
DataTable dt = DbProviderFactories.GetFactoryClasses();
Vous récupérez une table avec l’ensemble des Providers installés et bien entendu System.Data.SqlServerCe n’est pas dans la liste.
L’utilisation des objets SqlCeConnection donnent un résultat positif.
Pour ma part, la quatrième solution doit être envisagée afin d’offrir à l’application un support sur les autres types de bases de données. Et après avoir abandonné les Logging Application Blocks d’Enterprise Library, je me déleste du seul bloc que j’utilisais jusque là. Reste néanmoins a tester les autres bases de données avec cette nouvelle architecture.
3. Pour en savoir plus :
Enterprise Library 3.1
MySQL pour Enterprise Library, EntLib Contrib
Provider ADO.Net MySQL. Il se peut que vous deviez rebuilder le projet EntLib Contrib avec la version du provider MySQL que vous utilisez.
Runtime Sql Server Compact Edition