2010-11-11 2 views
0

Я пытаюсь обрабатывать вставку новой основной записи и связанных дочерних записей в 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 правильно установлено, и вставка успешно завершена.

Я чувствую, что мне не хватает чего-то тривиального, но что я делаю неправильно?

ответ

0

Вы кодировали для каскадирования? Я этого не вижу. Попробуй это.

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 

Вы можете прочитать: DataTable Constraints (ADO.NET)

EDIT: Я не понимаю эту часть

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

Почему вы назначая всех строк "newBookingID? Из этого я предполагаю, что первичные ключи могут быть не определены для наборов данных. Если бы они были, линия назначения должна была вызвать некоторую ошибку.

+0

Не зависит ли отношение внешнего ключа автоматически, если вы назначаете DataRelation? – Cruachan

+0

Я сомневаюсь. DataRelation - это просто отношение. Вы можете проверить это в дизайнере набора данных. Ограничение постороннего ключа должно быть явно объявлено. –

+0

Я сделал, и все. На самом деле я обнаружил, что проблема заключается в посторонней записи и ничего общего с этим кодом, но ответ принят, потому что то, что вы говорите, в основном правильное. – Cruachan