Как обновить родительские и дочерние таблицы набора данных с помощью автоматически сгенерированного ключа идентификации? - PullRequest
6 голосов
/ 31 мая 2009

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

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

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

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

Можно ли сделать такую ​​вещь в наборе данных, который позаботится об автоматически сгенерированном столбце для родительских и дочерних таблиц?

Спасибо

ABB

Ответы [ 3 ]

4 голосов
/ 18 июля 2011

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

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

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

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

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

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

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

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

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

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


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


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

3 голосов
/ 02 мая 2012

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

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

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

  3. Как только вы вызовете Update для родительской таблицы с помощью tableadapter, новые строки связанной дочерней таблицы будут иметь правильный parentID AUTOMATICALLY.

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

'--- 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)

Надеюсь, это поможет!

0 голосов
/ 24 октября 2010

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

...