Как я могу вставить родительские и дочерние строки SQL 2008 в одну транзакцию, используя VB.NET? - PullRequest
1 голос
/ 13 ноября 2010

Во-первых, немного предыстории (значительно упрощено): у меня есть два класса, один из которых называется Entity , а другой - Item , который является подклассом Entity.Каждый из них сохраняет свои индивидуальные свойства в отдельных таблицах SQL 2008, используя TableAdapters, сгенерированный строго типизированным DataSet.Класс Entity имеет метод Save (), который выглядит следующим образом:

Public Sub Save()
  entityTableAdapter.Update(entityRow)
End Sub

, а класс Item имеет метод Save, который выглядит следующим образом:

Public Overrides Sub Save()
  MyBase.Save
  itemTableAdapter.Update(itemRow)
End Sub

Это работает хорошо, за исключением того, чтоесли вставка строки Item не удалась, то я остался со строкой потерянного объекта в базе данных, поэтому я расширил методы TableAdapters и Save для использования транзакции следующим образом:

Метод сохранения объекта:

Public Sub Save(tx as SqlTransaction)
  entityTableAdapter.Connection = tx.Connection
  entityTableAdapter.Transaction = tx
  entityTableAdapter.Update(entityRow)
End Sub

Метод сохранения элемента:

Public Overrides Sub Save()
  // setup the transaction:
  dim cn as SqlConnection = itemTableAdapter.Connection
  cn.Open
  dim tx as Sql Transaction = cn.BeginTransaction
  // save the base object properties:
  MyBase.Save(tx)
  // save this object's properties:
  itemTableAdapter.Connection = cn
  itemTableAdapter.Transaction = tx
  itemTableAdapter.Update(itemRow)
  // commit the transaction
  tx.Commit
End Sub

Теперь, когда я пытаюсь сохранить новый элемент, все работает до itemTableAdapter.Update (itemRow), где я получаю ошибку, похожую на

Оператор INSERT конфликтует с ограничением FOREIGN KEY ... столбец 'EntityID'

Действительно, таблица SQL не содержит строки в таблице Entity с необходимым идентификатором на этом этапе, поскольку транзакция выполняетсяне завершено.

Я поступаю неправильно?Моя цель состоит в том, чтобы предотвратить вставку записи Entity, если вставка записи Item не удалась.Я мог бы написать код, чтобы снова удалить запись Entity, но это не кажется мне очень элегантным ...

Приведенный выше код был значительно упрощен, чтобы проиллюстрировать проблему.Я рад опубликовать более подробную информацию, если это поможет.

Заранее спасибо за любую помощь!

JE

1 Ответ

0 голосов
/ 13 ноября 2010

Способ обработки подобных ситуаций в некоторых базах данных (например, Oracle, PostgreSQL) заключается в использовании отсроченных ограничений. К сожалению, похоже, что SQL Server еще не поддерживает отложенные ограничения. Единственное, о чем я могу думать, это добавить логику в ваше приложение, чтобы удалить ненужный объект, если вставка элемента не удалась по какой-то другой причине.

Делись и наслаждайся.

...