2010-11-11 19 views
0

Je tente de gérer l'insertion d'une nouvelle fiche et des enregistrements enfants associés dans Winforms à l'aide de IronPython (développement dans SharpDevelop 4) par rapport à SQL Server, bien que je pense que ce soit un problème général ADO.NET. Le formulaire n'a jamais qu'une seule fiche (réservation) et plusieurs enregistrements de détail (lignes). Si la fiche existe déjà, je peux insérer des enregistrements enfants sans problème, mais mes relations ne semblent pas être en cascade si un nouvel enregistrement de réservation est ajouté.Relation maître-détail non en cascade sur insertion dans ADO.NET

Code spécifique - tout d'abord ajouter ma relation comme suit:

parentColumn = self._dataSetBookings.Tables["booking"].Columns["intBookingID"] 
childColumn = self._dataSetBookings.Tables["lines"].Columns["intBookingID"] 
bookingRelationship = DataRelation("mediabooking",parentColumn,childColumn,True) 
self._dataSetBookings.Relations.Add(bookingRelationship) 
self._dataSetBookings.EnforceConstraints = True 

intBookingID est une colonne d'identité sur la table de réservation

Ma appliquer la procédure de mise à jour ressemble à ceci, notez l'événement ajouté sur la ligne mise à jour . Les commandes SQL utilisées sont effectivement « select * d'où intBookingID = @intBookingID)

# update booking 
adapter = SqlDataAdapter() 
adapter.RowUpdated += self.AdapterUpdateBooking 
cmd = adapter.SelectCommand = self.conn.CreateCommand() 

cmd.CommandText = self.bookingSqlCmd 
parameter = cmd.Parameters.Add("@intBookingID", SqlDbType.Int) 
parameter.Value = self.BookingID 

builder = System.Data.SqlClient.SqlCommandBuilder(adapter) 
adapter.InsertCommand = builder.GetInsertCommand() 
adapter.UpdateCommand = builder.GetUpdateCommand() 
adapter.Update(self._dataSetBookings,"booking") 

# update lines 
adapter = SqlDataAdapter() 
cmd = adapter.SelectCommand = self.conn.CreateCommand()    
cmd.CommandText = self.lineSqlCmd 
parameter = cmd.Parameters.Add("@intLineBookingID", SqlDbType.Int) 
parameter.Value = self.BookingID 

builder = System.Data.SqlClient.SqlCommandBuilder(adapter) 
adapter.InsertCommand = builder.GetInsertCommand() 
adapter.UpdateCommand = builder.GetUpdateCommand() 
adapter.UpdateCommand = builder.GetDeleteCommand()  
adapter.Update(self._dataSetBookings,"lines") 

Et enfin l'événement RowUpdated - qui se déclenche une seule fois contre la ligne de réservation afin que nous puissions obtenir l'identité de l'enregistrement juste inséré

En traçant cela à travers lorsque les mises à jour sont appliquées la valeur d'ID correcte est récupérée par l'appel "SELECT @@ IDENTITY" pour un nouvel enregistrement (SCOPE_IDENTITY renvoie null, que je ne comprends pas et peut être un indice?) . Toutefois, lorsque la valeur est appliquée au champ intBookingID dans la table principale (réservation), elle ne met pas en cascade le champ intBookingID de mise à jour dans la table de détails (lignes) et l'insertion échoue.

Toutefois, si l'enregistrement principal (réservation) a été chargé à partir de la base de données et que de nouvelles lignes ont été ajoutées, la relation fonctionne, le champ intBookingID est correctement défini et l'insertion réussit. Je pense que je dois manquer quelque chose d'anodin, mais qu'est-ce que je fais de mal?

Répondre

0

Avez-vous codé pour la cascade? Je ne le vois pas. Essaye ça.

ForeignKeyConstraint oFKey; 
oFKey = new ForeignKeyConstraint("BookingForeignkey", parentColumn, childColumn); 
oFKey.DeleteRule = Rule.Cascade; 
oFKey.UpdateRule = Rule.Cascade; 
oFKey.AcceptRejectRule = AcceptRejectRule.Cascade; 
self._dataSetBookings.Tables["booking"].Constraints.Add(oFKey); 
self._dataSetBookings.EnforceConstraints = True 

Vous pouvez lire ceci: DataTable Constraints (ADO.NET)

EDIT: Je ne comprends pas cette partie

if newBookingID != System.DBNull: 
     for bookingRow in self._dataSetBookings.Tables["booking"].Rows: 
      bookingRow["intBookingID"] = newBookingID 

Pourquoi vous attribuez toutes les lignes de newBookingID? J'en déduis que les clés primaires n'ont peut-être pas été définies pour les ensembles de données. Si c'était le cas, la ligne d'affectation doit avoir généré une erreur.

+0

Une relation de clé étrangère n'est-elle pas affectée automatiquement lorsque vous affectez une valeur DataRelation? – Cruachan

+0

Je doute. Une DataRelation est juste une relation simple. Vous pouvez vérifier cela dans le concepteur de jeu de données. Une contrainte de clé étrangère doit être explicitement déclarée. –

+0

Je l'ai fait, et c'est le cas. En fait, j'ai trouvé que le problème était un encart externe et rien à voir avec ce code - mais une réponse acceptée parce que ce que vous dites est en grande partie correct. – Cruachan