Как обновить родительские и дочерние таблицы набора данных с помощью автоматически созданного ключа идентификации?

StackOverflow https://stackoverflow.com/questions/931630

  •  06-09-2019
  •  | 
  •  

Вопрос

Я использую наборы данных ADO.NET в своих приложениях VB.У меня есть типизированный набор данных с одной родительской таблицей и множеством дочерних таблиц.Я хочу сгенерировать ключ идентификации, когда я вставляю данные в родительскую таблицу, а затем обновляю данные во всех дочерних таблицах с помощью того же ключа (как ключ Foregin).

Наконец, я хочу обновить набор данных в базе данных (SQL Server08).

Что ж, описанное выше может быть возможным, если сначала вставить родительскую таблицу напрямую в базу данных, получить столбец Identity, а затем использовать ее для дочерних таблиц.

Но я хочу, чтобы это была автоматическая операция (например, LINQ to SQL, которая заботится о первичном и внешнем ключе в контексте данных).

Возможно ли такое в наборе данных, который заботится об автоматически создаваемом столбце для родительских и дочерних таблиц?

Спасибо,

АББ

Нет правильного решения

Другие советы

Я думаю, что это должно быть более очевидно и должно работать без каких-либо настроек.Но все же это довольно легко.

Решение состоит из двух частей:

  1. Создавать DataRelation между дочерними и родительскими таблицами и настроить каскадирование при обновлениях.Таким образом, при изменении идентификатора родителя все дочерние элементы будут обновляться.

    Dim rel = ds.Relations.Add(parentTab.Columns("Id"), childTab.Columns("ParentId"))
    rel.ChildKeyConstraint.UpdateRule = Rule.Cascade
    
  2. Команды вставки и обновления набора данных являются двусторонними:Если есть какие -либо выходные параметры или любые возвращаемые строки данных, они будут использоваться для обновления строки наборов данных, которая вызвала обновление.

    Это наиболее полезно для этой конкретной проблемы:Получение автогенерированных столбцов обратно к применению.Помимо идентификатора, это может быть, например, столбец метки времени.Но идентичность наиболее полезна.

    Все, что нам нужно сделать, это установить команду вставки для возврата идентификатора.Есть несколько способов сделать это, например:

    а) Использование хранимой процедуры с выходным параметром.Это наиболее переносимый способ среди «настоящих» баз данных.

    б) Использование нескольких операторов SQL, последний из которых возвращает вставленную строку.Это AFAIK, специфичный для SQL Server, но самый простой:

    insert into Parent (Col1, Col2, ...) values (@Col1, @Col2, ...);
    select * from Parent where Id = SCOPE_IDENTITY();
    

После настройки все, что вам нужно сделать, это создать родительские строки с помощью Idкоторые уникальны (в пределах одного набора данных), но невозможны в базе данных.Отрицательные числа обычно являются хорошим выбором.Затем, когда вы сохраните изменения набора данных в базе данных, все новые родительские строки станут реальными. Idиз базы данных.


Примечание:Если вам приходится работать с базой данных без поддержки нескольких операторов и без хранимых процедур (например,Access), вам нужно будет настроить обработчик событий на RowUpdated событие в адаптере родительской таблицы.В ханлере вам нужно получить идентичность с select @@IDENTITY команда.


Некоторые ссылки:

Несколько вещей, на которые стоит обратить внимание.

  1. Да, вам определенно нужны отношения, назначенные для обеих таблиц.Вы можете проверить это в редакторе xsd (дважды щелкните файл xsd).По умолчанию отношение установлено как «только отношение», которое не имеет никаких «правил обновления».Отредактируйте это отношение, перейдя в «Редактировать отношение» и выбрав «Только ограничение внешнего ключа» или «Оба ~~~».И нужно установить «Правило обновления» как «Каскад»!«Удалить правило» зависит от вас.

  2. Теперь, когда вы используете идентификатор новой строки родительской таблицы (автоинкремент) для новых строк дочерней таблицы в качестве внешнего ключа, вам необходимо сначала добавить родительскую строку в таблицу, прежде чем использовать идентификатор новой родительской строки.

  3. Как только вы вызываете Update для родительской таблицы с помощью tableadapter, новые строки связанной дочерней таблицы будут иметь правильный родительский ID АВТОМАТИЧЕСКИ.

Мои простые фрагменты кода:

'--- Make Parent Row
Dim drOrder as TOrderRow = myDS.TOder.NewTOrderRow
drOrder.SomeValue = "SomeValue"
myDS.TOrder.AddTOrderRow(drOrder) '===> THIS SHOULD BE DONE BEFORE CHILD ROWS

'--- Now Add Child Rows!!! there are multiple ways to add a row into tables....
myDS.TOrderDetail.AddTOrderDetailRow(drOrder, "detailValue1")
myDS.TOrderDetail.AddTOrderDetailRow(drOrder, "detailvalue2")
'....
'....

'--- Update Parent table first
myTableAdapterTOrder.Update(myDS.TOrder)
'--- As soon as you run this Update above for parent, the new parent row's AutoID(-1)
'--- will become real number given by SQL server. And also new rows in child table will
'--- have the updated parentID

'--- Now update child table
myTableAdapterTOrderDetail.Update(myDS.TOrderDetail)

Я надеюсь, что это помогает!

И если вы не хотите использовать наборы данных и при этом получать идентификаторы, назначенные дочерним элементам, и получать идентификаторы, чтобы вы могли обновить свою модель:https://danielwertheim.wordpress.com/2010/10/24/c-batch-identity-inserts/

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top