Я пытаюсь обрабатывать вставку новой основной записи и связанных дочерних записей в Winforms с использованием IronPython (разрабатывается в SharpDevelop 4) против SQL Server, хотя я считаю, что это общая проблема ADO.NET. Форма только когда-либо имеет одну главную запись (бронирование) и множество подробных записей (строк). Если основная запись уже существует, я могу вставить дочерние записи без проблем, но мои отношения не кажутся каскадными, если добавлена новая запись о бронировании.Связи Master-Detail, не связанные с вставкой в ADO.NET
Специальный код - во-первых, я добавляю свои отношения следующим образом:
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 является столбцом идентификаторов в таблице бронирования
Мой применить процедуру обновления выглядит следующим образом, обратите внимание на событие добавлен ряд обновляется , Команды SQL используются эффективно «выбрать * откуда 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")
И, наконец, событие RowUpdated - который только срабатывает один раз против строки бронирования, чтобы мы могли получить идентификатор записи только что вставили
def AdapterUpdateBooking(self, sender, e):
cmd = self.conn.CreateCommand()
#cmd.CommandText = "SELECT SCOPE_IDENTITY()" - this does not work!
cmd.CommandText = "SELECT @@IDENTITY "
newBookingID = cmd.ExecuteScalar()
if newBookingID != System.DBNull:
for bookingRow in self._dataSetBookings.Tables["booking"].Rows:
bookingRow["intBookingID"] = newBookingID
Проводя это, когда применяются обновления, правильное значение ID извлекается вызовом «SELECT @@ IDENTITY» для новой записи (но SCOPE_IDENTITY возвращает значение null, которое я не понимаю и может быть ключом?) , Однако, когда значение применяется к полю intBookingID в таблице Master (бронирование), оно не обновляет поле intBookingID update в таблице деталей (строк), и вставка не выполняется.
Однако, если запись с Master (бронирование) была загружена из базы данных и добавлены новые строки, отношения действительно работают, поле intBookingID правильно установлено, и вставка успешно завершена.
Я чувствую, что мне не хватает чего-то тривиального, но что я делаю неправильно?
Не зависит ли отношение внешнего ключа автоматически, если вы назначаете DataRelation? – Cruachan
Я сомневаюсь. DataRelation - это просто отношение. Вы можете проверить это в дизайнере набора данных. Ограничение постороннего ключа должно быть явно объявлено. –
Я сделал, и все. На самом деле я обнаружил, что проблема заключается в посторонней записи и ничего общего с этим кодом, но ответ принят, потому что то, что вы говорите, в основном правильное. – Cruachan