2010-10-14 3 views
2

J'ai récemment commencé à travailler sur un projet déjà en cours depuis plusieurs années. L'application est écrite en C# en utilisant Windows Forms pour l'interface utilisateur et SQLite pour la base de données. La base de données est actuellement accessible en utilisant ADO.NET via l'espace de noms System.Data.SQLite. De temps en temps, les clients ont reçu des mises à jour d'applications et de bases de données, mais pas tous en même temps, ce qui fait qu'il existe de nombreuses versions structurellement différentes de la base de données. Pour aggraver les choses, les clients peuvent ajouter leurs propres champs aux tables de l'application pour activer les rapports personnalisés, etc. Ainsi, le nombre de bases de données différentes est hors de contrôle. Lorsque des améliorations ont été apportées aux fonctionnalités, de plus en plus de code «if-then-else» ont été ajoutés pour que l'application continue à fonctionner pour toutes ces variations de base de données. De plus, SQLite a la fâcheuse caractéristique que les valeurs dans les champs peuvent être stockées comme n'importe quel type et pas seulement le type défini dans l'instruction create table. Il est courant que des données soient importées à partir de fichiers CSV à partir d'Excel avec des valeurs de date/heure incorrectes que SQLite importe, mais sous le code, nous obtenons toutes sortes d'exceptions de type non valide.Principaux problèmes lors de la migration des bases de données SQLite "Legacy" pour utiliser Entity Framework

Je veux mettre un terme à tout cela. Afin de nettoyer la base de données, je suis à l'origine d'une conception de base de données standard qui ne changera pas à moins que nous ne publions une mise à jour officielle avec le code pour migrer automatiquement les données.

J'ai pris la dernière conception "ad-hoc" et, sans changer les noms de table et de champ, l'ai rendu au moins Entity Framework amical en s'assurant que les clefs primaires sont définies pour les champs existants .

Je tente maintenant de migrer les différentes bases de données existantes une par une. J'utilise une technique de chargement de tous les enregistrements de chaque table en utilisant "SELECT * FROM [LEGACY_TABLE];" et créer de nouveaux objets Entity Framework en utilisant new EF_Table() { ID = GetValue<long>(dr, "ID"), Description = GetValue<string>(dr, "Description"), };. J'ai défini GetValue pour gérer la conversion des données mal formatées et DBNull références etc.

Mon problème majeur est maintenant que la plupart des tables ont des clés définies comme « INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL » qui ne permet pas l'entité Framework pour affecter les valeurs de clé en cours à partir de la base de données existante. Dans le processus de migration, je dois m'assurer que les clés primaires restent les mêmes car aucune relation de clé étrangère n'est définie et les valeurs de clé primaire existantes sont stockées en dehors de la base de données dans les données de configuration de l'application.

J'ai cherché une solution, mais je ne peux pas la voir. J'aurais pensé que ce genre de problème - la migration et/ou le nettoyage d'une base de données SQLite existante - aurait été un problème résolu.

Quelqu'un peut-il me diriger dans une direction productive pour résoudre ce problème?

Répondre

1

Eh bien, c'était assez simple de contourner ce problème.

Il s'avère que les clés primaires définies par Entity Framework dans le fichier "edmx" ont la propriété StoreGeneratedPattern="Identity" pour les clés primaires à incrémentation automatique. En modifiant la valeur à StoreGeneratedPattern="None", Entity Framework autorise les mises à jour de la clé primaire par simple affectation de code.

Ainsi, par exemple, quand j'ai cette définition de la table:

CREATE TABLE "FM_Location" (
    [ID] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
    [Location] TEXT 
); 

Puis le suivant élément "EntityType" est défini dans le fichier "edmx":

<EntityType Name="FM_Location"> 
    <Key> 
     <PropertyRef Name="ID" /> 
    </Key> 
    <Property Name="ID" Type="integer" Nullable="false" 
      StoreGeneratedPattern="Identity" /> 
    <Property Name="Location" Type="nvarchar" /> 
</EntityType> 

J'ai changé « Identité "à" None "comme ceci:

<EntityType Name="FM_Location"> 
    <Key> 
     <PropertyRef Name="ID" /> 
    </Key> 
    <Property Name="ID" Type="integer" Nullable="false" 
      StoreGeneratedPattern="None" /> 
    <Property Name="Location" Type="nvarchar" /> 
</EntityType> 

Je l'ai fait avec tous les champs d'incrémentation automatique et je pouvais faire le mig ration.

Questions connexes