Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Entity Framework et la compatibilité arrière (problème Datetime2).

[new:05/07/2010]Vous possédez un OS récent, comme Windows 7, vous développez avec les outils les plus modernes (disons VS 2010 au hasard) et, bien entendu votre base de données installée en local est SQL Server 2008. D’une part parce que c’est une bonne version, mais surtout parce que vous n’avez pas trop le choix… Vous créez une application pour un client qui utilise SQL Server 2005 et là, pof! dès qu’il exécute votre logiciel il y a une exception du genre “The version of SQL Server in use does not support datatype 'datetime2”…

Vous cherchez alors comme un fou dans votre code, dans les méta données de la base où vous avez bien pu utiliser le type “datetime2”. Mais rien. Que pouic. Néant.

La base de données n’utilise que des types SQL 2005, elle-même est bien une base SQL 2005, quand au code, vous en être certain, jamais aucune référence à Datetime2 nulle part.

Quel est ce mystère ?

Il se cache dans l’Entity Framework. Lorsque vous avez créé le modèle vous étiez connecté à votre serveur SQL Server 2008, peu importe que la base de données soit une base SQL 2005 ou non. C’est le serveur qui compte.

Or, le designer de l’Entity Framework optimise le modèle selon la version du serveur. C’est à dire que voyant que votre serveur est SQL 2008, il a stocké des informations permettant d’optimiser les requêtes pour cette version là.

De fait, lorsque le logiciel est lancé, chez vous, ça passe impeccable… Mais chez le client ça bug. EF fabrique des requêtes et des classes à la volée, et il utilise notamment le type DateTime2 de SQL Server 2008 qu’il juge plus efficace que le type DateTime de la version précédente. Mais comme SQL Server 2005 ne sait pas traiter ce type là, forcément ça coince.

La solution

Une fois qu’on sait c’est très simple.

Il suffit de charger le fichier .edmx (le modèle EF) dans un éditeur XML (ou le bloc-notes au pire) et de repérer en début de fichier généralement la balise suivante :

   1: <Schema Namespace="Syo_DataModel.Store" Alias="Self" 
   2:   Provider="System.Data.SqlClient" ProviderManifestToken="2008" 
   3:   xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">

Comme vous le constater elle contient un attribut “ProviderManifestToken” qui, pour l’heure, indique la valeur “2008”.

C’est simple : changer cette valeur en “2005” et dès lors le modèle sera “optimisé” pour SQL Server 2005. Cela continue de fonctionner sous SQL Server 2008 (si la base elle même est bien au format 2005).

Conclusion

Une solution très simple pour une erreur qui peut prendre la tête. A noter dans vos tablettes donc !

Et Stay Tuned !

blog comments powered by Disqus