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?
Une relation de clé étrangère n'est-elle pas affectée automatiquement lorsque vous affectez une valeur DataRelation? – Cruachan
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. –
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