Поделиться через


Иерархическое обновление в разработке .NET Framework

Замечание

Классы DataSet и связанные классы являются устаревшими технологиями .NET Framework с начала 2000-х годов, которые позволяют приложениям работать с данными в памяти, пока приложения отключены от базы данных. Технологии особенно полезны для приложений, которые позволяют пользователям изменять данные и сохранять изменения обратно в базу данных. Хотя наборы данных являются проверенными успешными технологиями, рекомендуемый подход для новых приложений .NET заключается в использовании Entity Framework Core. Entity Framework предоставляет более естественный способ работы с табличными данными в виде объектных моделей и имеет более простой интерфейс программирования.

Иерархическое обновление относится к процессу сохранения обновленных данных (из набора данных с двумя или более связанными таблицами) обратно в базу данных при сохранении правил целостности ссылок. Ссылочная целостность относится к правилам согласованности, предоставляемым ограничениями в базе данных, которые управляют поведением вставки, обновления и удаления связанных записей. Например, именно ссылочная целостность гарантирует создание записи клиента до того, как разрешается создание заказов для этого клиента. Дополнительные сведения о связях в наборах данных см. в разделе "Связи" в наборах данных.

Функция иерархического обновления использует TableAdapterManager для управления TableAdapter в типизированном наборе данных. Компонент TableAdapterManager является классом, созданным Visual Studio, а не типом .NET. При перетаскивании таблицы из окна источников данных на страницу Windows Form или WPF Visual Studio добавляет переменную типа TableAdapterManager в форму или страницу, и вы увидите ее в конструкторе в области компонентов. Подробные сведения о TableAdapterManager классе см. в разделе Справочника TableAdapterManager tableAdapters.

По умолчанию набор данных обрабатывает связанные таблицы как "только отношения", что означает, что он не применяет ограничения внешнего ключа. Этот параметр можно изменить во время разработки с помощью конструктора наборов данных. Выберите линию отношения между двумя таблицами, чтобы открыть диалоговое окно "Отношение ". Внесенные здесь изменения определяют то, как TableAdapterManager будет вести себя при отправке изменений в связанные таблицы обратно в базу данных.

Включение иерархического обновления в наборе данных

По умолчанию иерархическое обновление включено для всех новых наборов данных, которые добавляются или создаются в проекте. Включите или отключите иерархическое обновление, установив свойство Иерархическое обновление типизированного набора данных в значение True или False.

Параметр иерархического обновления

Создание нового отношения между таблицами

Чтобы создать новое отношение между двумя таблицами, в конструкторе наборов данных выберите заголовок каждой таблицы, а затем щелкните правой кнопкой мыши и выберите "Добавить отношение".

Иерархическое меню добавления реляционного обновления

Общие сведения о ограничениях внешнего ключа, каскадных обновлениях и удалениях

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

По умолчанию таблицы данных в наборе данных создаются с помощью связей (DataRelation), которые соответствуют связям в базе данных. Однако связь в наборе данных не создается как ограничение внешнего ключа. Он DataRelation настраивается как "Только отношение" без UpdateRule или DeleteRule в действии.

По умолчанию каскадные обновления и каскадные удаления отключены, даже если связь базы данных устанавливается с каскадными обновлениями или каскадными удалениями. Например, создание нового клиента и нового заказа, а затем попытка сохранить данные может привести к конфликту с ограничениями внешнего ключа, определенными в базе данных. Дополнительные сведения см. в разделе "Отключение ограничений при заполнении набора данных".

Настройка порядка выполнения обновлений

Задание порядка выполнения обновлений задает порядок отдельных вставок, обновлений и удалений, необходимых для сохранения всех измененных данных во всех таблицах набора данных. При включении иерархического обновления сначала выполняются вставки, затем — обновления, и, наконец, — удаления. Предоставляет TableAdapterManager свойство, которое можно задать для выполнения сначала обновлений, затем вставок, а затем удалений.

Замечание

Важно понимать, что порядок обновления включает все. То есть при выполнении обновлений вставка и удаление выполняются для всех таблиц в наборе данных.

Чтобы задать свойство UpdateOrder, после перетаскивания элементов из окна Источники данных на форму выберите TableAdapterManager в области компонента и задайте свойство UpdateOrder в окне Свойства.

Создание резервной копии набора данных перед выполнением иерархического обновления

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

Однако иногда может потребоваться восстановить набор данных из резервной копии. Один из примеров этого может произойти при использовании значений автоинкремента. Например, если операция сохранения не выполнена, значения автоматического увеличения не сбрасываются в наборе данных, а набор данных продолжает создавать значения автоматического увеличения. Это оставляет пробел в нумерации, который может быть неприемлемым в вашем приложении. В ситуациях, когда это является проблемой, TableAdapterManager предоставляет свойство BackupDataSetBeforeUpdate, заменяющее существующий набор данных резервной копией, если транзакция не удается.

Замечание

Резервная копия находится только в памяти во время TableAdapterManager.UpdateAll выполнения метода. Поэтому доступа к этому резервному набору данных через программный интерфейс нет, так как он заменяет набор данных-источник или выходит за пределы области видимости сразу по завершении работы метода TableAdapterManager.UpdateAll.

Изменение созданного кода сохранения для выполнения иерархического обновления

Сохраните изменения из связанных таблиц данных в наборе данных в базу данных путем вызова TableAdapterManager.UpdateAll метода и передачи имени набора данных, содержащего связанные таблицы. Например, запустите TableAdapterManager.UpdateAll(NorthwindDataset) метод для отправки обновлений из всех таблиц в NorthwindDataset в серверную базу данных.

После удаления элементов из окна источников данных код автоматически добавляется в Form_Load событие, чтобы заполнить каждую таблицу ( TableAdapter.Fill методы). Код также добавляется в событие BindingNavigator нажатия кнопки "Сохранить" для сохранения данных из набора данных обратно в базу данных (TableAdapterManager.UpdateAllметод).

Созданный код сохранения также содержит строку кода, которая вызывает CustomersBindingSource.EndEdit метод. В частности, он вызывает EndEdit метод первого BindingSource, добавляемого в форму. Другими словами, этот код создается только для первой таблицы, перетаскиваемой из окна источников данных в форму. Вызов EndEdit фиксирует все изменения, которые находятся в процессе в любых элементах управления, привязанных к данным, которые в настоящее время редактируются. Таким образом, если элемент управления с привязкой к данным по-прежнему в фокусе и нажимается кнопка «Сохранить», все ожидающие изменения в этом элементе управления фиксируются до фактического сохранения (метод TableAdapterManager.UpdateAll).

Замечание

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

  1. Дважды щелкните кнопку "Сохранить " на BindingNavigator вкладке "Форма1 " в редакторе кода.

  2. Добавьте строку кода для вызова OrdersBindingSource.EndEdit метода после строки, которая вызывает CustomersBindingSource.EndEdit метод. Код в событии нажатия кнопки "Сохранить " должен выглядеть следующим образом:

    this.Validate();
    this.customersBindingSource.EndEdit();
    this.ordersBindingSource.EndEdit();
    this.tableAdapterManager.UpdateAll(this.northwindDataSet);
    

Помимо фиксации изменений в связанной дочерней таблице перед сохранением данных в базе данных, может потребоваться зафиксировать только что созданные родительские записи перед добавлением новых дочерних записей в набор данных. Другими словами, может потребоваться добавить новую родительскую запись (Customer) в набор данных, прежде чем ограничения внешнего ключа позволяют добавлять новые дочерние записи (Orders) в набор данных. Для этого можно использовать дочернее BindingSource.AddingNew событие.

Замечание

Требуется ли внесение новых родительских записей, зависит от типа элемента управления, используемого для привязки к источнику данных. В этом пошаговом руководстве вы используете отдельные элементы управления для привязки к родительской таблице. Для этого требуется дополнительный код для фиксации новой родительской записи. Если бы родительские записи отображались в сложном элементе управления привязкой, таком как DataGridView, дополнительный вызов родительской записи EndEdit был бы не нужен. Это связано с тем, что базовая функция привязки данных элемента управления обрабатывает фиксацию новых записей.

Добавление кода для фиксации родительских записей в наборе данных перед добавлением новых дочерних записей

  1. Создайте обработчик событий для события OrdersBindingSource.AddingNew.

    • Откройте Форму1 в режиме конструктора, выберите OrdersBindingSource в области компонентов, выберите "События " в окне "Свойства ", а затем дважды щелкните событие "ДобавитьNew ".
  2. Добавьте строку кода в обработчик событий, который вызывает CustomersBindingSource.EndEdit метод. Код в обработчике OrdersBindingSource_AddingNew событий должен выглядеть следующим образом:

    this.customersBindingSource.EndEdit();
    

Ссылка на TableAdapterManager

По умолчанию TableAdapterManager класс создается при создании набора данных, содержащего связанные таблицы. Чтобы предотвратить создание класса, измените значение Hierarchical Update свойства набора данных на false. При перетаскивании таблицы, которая имеет отношение к области конструктора страницы Windows Form или WPF, Visual Studio объявляет переменную члена класса. Если вы не используете привязку данных, необходимо вручную объявить переменную.

Класс TableAdapterManager не является типом .NET. Поэтому его невозможно найти в документации. Он создается во время разработки в рамках процесса создания набора данных.

Ниже приведены часто используемые методы и свойства TableAdapterManager класса:

Член Описание
UpdateAllМетод Сохраняет все данные из всех таблиц данных.
Свойство BackUpDataSetBeforeUpdate Определяет, следует ли создавать резервную копию набора данных перед выполнением метода TableAdapterManager.UpdateAll. Булево значение.
свойство tableNameTableAdapter TableAdapterПредставляет объект . TableAdapterManager Созданный объект содержит свойство для каждого TableAdapter управляемого элемента управления. Например, набор данных с таблицами "Клиенты" и "Заказы" создается с TableAdapterManager, который содержит свойства CustomersTableAdapter и OrdersTableAdapter.
Свойство UpdateOrder Управляет порядком отдельных команд вставки, обновления и удаления. Задайте для этого одно из значений перечисления TableAdapterManager.UpdateOrderOption .

По умолчанию UpdateOrder установлено значение InsertUpdateDelete. Это означает, что вставки, а затем обновления, а затем удаления выполняются для всех таблиц в наборе данных.