2009-11-21 5 views
1

J'ai une collectionC# DataTable: Ajouter une nouvelle ligne lance erreur en utilisant le terrain AutoInc

List<Employee> employees; 

-je utiliser un DataTable et charger tous les enregistrements (de la table MDB) lorsque Form1.Loads et ajouter ces enregistrements à la liste (collection) donc je travaille avec eux en mémoire.

Maintenant, quand j'ajoute un nouvel employé à la collecte, je dois ajouter aussi à la table mdb ... donc je fais:

DataRow rowemployee = Program.tblEmployee.NewRow(); 
rowemployee["name"] = tb_Name.Text; 
rowemployee["address"] = tb_Address.Text; 
//...all the other fields 
Program.tblEmployee.AddRow(rowemployee); 

L'IDE génère une erreur concernant la colonne « id » doit n'a pas de valeur nulle ou ne doit pas être vide.
Comme la table mdb a une colonne id, tapez number, autoinc, comment dois-je réparer la classe Employee et les méthodes DataTable/Collections, de sorte que la colonne id est "ignorée" lors de l'ajout de nouvelles lignes?

Merci

Répondre

2

Le premier problème est que si la colonne id est incrémentée automatiquement dans votre base de données, l'objet DataColumn correspondant à dans votre DataTable est pas configuré pour incrémentation automatique. Vous devez définir ses propriétés AutoIncrement, AutoIncrementSeed et AutoIncrementStep. Une fois que vous faites cela, vous rencontrerez le deuxième problème, à savoir que vous avez deux graines d'auto-incrémentation différentes: celle de votre base de données et celle de votre DataTable. Même si ces deux graines commencent à la même valeur, il est trivial pour elles d'être désynchronisées: ajoutez une ligne à votre DataTable et une ligne différente à votre table de base de données, et maintenant vous avez deux lignes différentes avec le même ID.

Il s'agit d'un problème courant et sa solution commune consiste à utiliser une séquence de numérotation différente pour les lignes ajoutées au DataTable. Généralement, cela est fait en définissant la graine à 0 et l'étape à -1, de sorte que toutes les lignes que vous ajoutez au DataTable ont des ID inférieurs à 0. (Cela suppose bien entendu que tous les ID de votre base de données sont supérieur à 0.) Cela signifie qu'il n'y a aucune chance d'une collision ID entre les lignes ajoutées dans la base de données et les lignes ajoutées au DataTable.

Ensuite, lorsque vous mettez à jour en fait la base de données de la DataTable, après avoir inséré la ligne dans la base de données et son réel ID est attribué, vous modifiez l'ID dans le DataRow à la valeur correcte. Si la ligne participe aux relations de données en tant que parent, les mises à jour en cascade doivent être définies pour DataColumn, de sorte que la modification de l'ID de la ligne parent de sa valeur locale temporaire à sa valeur permanente modifie également les ID des lignes enfants associées.

L'une des nombreuses raisons d'utiliser des ensembles de données et des adaptateurs de table typés est que tout ce travail est fait automatiquement pour vous. Mais si vous n'utilisez pas d'adaptateurs de table, vous devrez le faire vous-même.Il y a un très bon exemple de ceci dans the ADO documentation

+0

OMFG ... c'est l'enfer! !! Je ne vais pas faire tout ça pour pouvoir ajouter un enregistrement à la table sans avoir de problèmes avec le champ id dans le tableau Je suppose que je vais utiliser la manière automatique – Enrique

+0

Ce n'est vraiment pas si mal. Il n'y a que trois choses à faire: configurer l'incrémentation automatique, mettre à jour l'ID après une insertion, et configurer votre DataRelations pour mettre en cascade les mises à jour - et vous n'avez qu'à faire la troisième chose si votre table participe aux relations. –

0

Comment avez-vous configuré la table?

Ce code provient du DataRow.ItemArray Property MSDN page qui illustre comment la propriété AutoIncrement est utilisée.

private DataTable MakeTableWithAutoIncrement() 
{ 
    // Make a table with one AutoIncrement column. 
    DataTable table = new DataTable("table"); 
    DataColumn idColumn = new DataColumn("id", 
     Type.GetType("System.Int32")); 
    idColumn.AutoIncrement = true; 
    idColumn.AutoIncrementSeed = 10; 
    table.Columns.Add(idColumn); 

    DataColumn firstNameColumn = new DataColumn("Item", 
     Type.GetType("System.String")); 
    table.Columns.Add(firstNameColumn); 
    return table; 
} 
+0

Mon fichier mdb avait une seule table, "Employé", qui a quelques champs, et a aussi une clé primaire définie sur autonumérique (autoinc). Quand j'ajoute des données dans ma liste <>, je dois aussi refléter ce changement dans le mdb, mais cela ne me permet pas de publier un nouvel enregistrement sans le champ id ... – Enrique

Questions connexes