Я пытался обработать вставку новой основной записи и связанных дочерних записей в Winforms, используя IronPython (разрабатывается в SharpDevelop 4) для SQL Server, хотя я думаю, что это общая проблема 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 - это, по сути, 'select * откуда 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
При отслеживании этого, когда применяются обновления, правильное значение идентификатора извлекается с помощью вызова «SELECT @@ IDENTITY» для новой записи (но SCOPE_IDENTITY возвращает ноль, что я не понимаю и может бытьключ?).Однако когда значение применяется к полю intBookingID в таблице Master (резервирование), оно не приводит к каскадному обновлению поля intBookingID в таблице подробностей (строк), и вставка завершается неудачно.
Однако, если основная запись (резервирование)был загружен из базы данных и добавлены новые строки, связь работает, поле intBookingID установлено правильно, и вставка прошла успешно.
Мне кажется, что я упускаю что-то тривиальное, но что я делаю не так?