Au fil des flows

19jan/120

SQLite et le support des clefs etrangeres

Posted by Fabien Arcellier

SQLite est un moteur de base de donnée très léger. Cette solution offre des possibilités différentes des solutions comme PostGreSQL, mySQL ou MSSql. Elle est directement intégrée à votre programme et n'utilise pas de processus séparé. L'intéret c'est que vous pouvez l'utiliser aussi simplement qu'un fichier en profitant de la puissance du langage SQL.

En ayant conçu mon shéma de base de donnée au départ, j'avais configuré les clefs étrangères et la liaison entre les différentes tables. Je m'attendai à ce que par défaut SQLite s'occupe de ces contraintes.

Le scénario que j'attendai est le suivant :

  • Si l'utilisateur supprime une ville, alors tous les immeubles et leurs appartements de cette ville sont supprimés
  • Si l'utilisateur supprime un immeuble, alors je veux supprimer tous les appartements de cet immeuble

Surprise lors des tests, ça ne se comportait pas du tout comme ça. Pourtant les règles de suppression étaient bien présentes dans le fichier de création de la base.

PRAGMA foreign_key

Par défaut, les clefs étrangères ne sont pas utilisés par sqlite. Il n'en tiendra pas compte. Lors de votre connexion, avant toute autre requête, vous devez exécuter la requête suivante :

PRAGMA foreign_keys = ON;

Je n'ai pas trouvé de moyen de les activer par défaut en permanence. Vous devez le faire à chaque connexion.

Pour ceux qui utilise le provider ADO.Net pour utiliser la base de donnée, vous pouvez le configurer dans votre chaine de connexion la commande suivante : foreign keys=true;.

Remplis sous: Non classé Aucun commentaire
3jan/125

System.IO.FileNotFoundException: Could not load file or assembly ‘System.Data.SQLite.dll’

Posted by Fabien Arcellier

Aujourd'hui, j'ai rencontré ce message d'erreur sur une application que je développe. Plaçons rapidement le contexte, il s'agit d'un outil développé avec .NET4 qui permet de gérer le contenu d'une base de donnée sqlite.

Ma machine de développement est sous Windows 7 64bits. Ce problème est apparu lors du test de l'application sur une machine équipée d'un Windows Vista 32bits.

Voici l'exception complète que j'ai relevé dans le trace.log :

02/01/2012 18:31:10
Exception Not handled
System.IO.FileNotFoundException: Could not load file or assembly 'System.Data.SQLite.dll' or one of its dependencies. Le module spécifié est introuvable.
File name: 'System.Data.SQLite.dll'
 ... [Suivi de son stacktrace]

La première piste que j'ai suivi, vu que je venai de la machine de développement, c'est l'absence du fichier System.Data.SQlite.dll dans le GAC. Cette piste m'a mené nulle part. L'erreur c'etait de se focaliser sur le type de l'exception FileNotFoundException.

Par hasard, en venant remplacer le fichier System.Data.SQLite.dll qui se trouvait à coté de l'application, j'ai obtenu un message d'erreur différent. Celui ci m'indiquait que la signature de l'assembly ne correspondait plus. Ca signifiait qu'il trouvait bien l'assembly System.Data.SQlite.dll mais qu'il n'arrivait pas à le charger

Au final, j'ai pu résoudre ce problème en utilisant une Dll différente. Sur la page de ce provider de données, plusieurs distributions sont proposées.

Sur la version qui me donnait une erreur, j'utilisai la version sqlite-netFx40-binary-bundle-Win32-2010-1.0.77.0.zip. En utilisant sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.77.0.zip, le problème n'apparaissait plus.

Quel est le souci  ?

A dire la vérité je n'en suis pas certain. Ayant parcouru la toile, certaines personnes semblent avoir  rencontré un problème très similaire.

Le fournisseur de donnée System.Data.SQLite.dll encapsule la librairie en code natif sqlite3.dll. Contrairement au code managé de System.Data.SQLite.dll, ce code ne peut s'exécuter que sur la plate forme à  laquelle il est destinée. La où je ne comprends pas c'est que ma plateforme cible à la compilation et de la dll ont été choisi pour avoir comme cible des processeurs x86, c'est à dire 32bits.

Le lien statique évite que le code soit chargé par l'OS pour pouvoir l'utiliser. Le programme vient attaquer directement les fonctions de la Dll. Je pense que c'est là où se trouve un morceau de l'explication. C'est le chargement qui est bloquant. Peut etre que le souci vient du wrapper autour de sqlite3.dll mais difficile de conclure...

Voici un shéma la différence entre un lien statique et un lien dynamique (tiré d'un sujet sur stackoverflow)

Comparaison Lien Statique Dynamique

Comparaison Lien Statique Dynamique

Avez vous déjà rencontré un problème similaire ? Avez vous une explication plus convaincante ?

 

 

Remplis sous: Non classé 5 Commentaires