Отримання значень ідентифікаторів або автонумерації

Первинним ключем в реляційної базі даних є стовпець або поєднання стовпців, які завжди містять унікальні значення. Якщо відомо значення первинного ключа, то можна знайти рядок, яка містить це значення. Такі СУРБД, як SQL Server, Oracle і Microsoft Access / Jet, підтримують створення стовпців з автоматично збільшуються значеннями, які можуть призначатися в якості первинних ключів. Ці значення формуються сервером у міру додавання рядків в таблицю. У SQL Server задається властивість ідентифікатора стовпця, в Oracle створюється послідовність Sequence, а в Microsoft Access створюється стовпець AutoNumber.

Для формування автоматично збільшуються значень також можна використовувати об'єкт DataColumn. присвоївши його властивості AutoIncrement значення true. Але це може привести до появи повторюваних значень в окремих примірниках DataTable. якщо в декількох клієнтських додатках будуть незалежно формуватися автоматично збільшуються значення. Застосування сервера для формування автоматично збільшуються значень дозволяє усунути потенційні конфлікти, оскільки кожен користувач може отримувати створювані сервером значення для кожної вставляється рядки.

Під час виклику методу Update об'єкта DataAdapter база даних може відправляти дані назад в додаток ADO.NET як вихідних параметрів або в вигляді першої повернутої записи результуючого набору інструкції SELECT, що виконується в тому ж пакеті, що і інструкція INSERT. Середа ADO.NET дозволяє отримувати ці значення і оновлювати відповідні стовпці в обновлюваному об'єкті DataRow.

Деякі СУБД, такі як Microsoft Access Jet, не підтримують вихідні параметри і не можуть обробляти кілька інструкцій в одному пакеті. Працюючи з ядром бази даних Jet, нове значення AutoNumber, створюване для вставленого рядка, можна отримати, виконавши окрему команду SELECT в обробнику подій RowUpdated об'єкта DataAdapter.

Підхід, альтернативний по відношенню до використання автоматично збільшується значення, полягає в застосуванні методу NewGuid об'єкта Guid для формування ідентифікатора GUID (глобально унікального ідентифікатора) на клієнтському комп'ютері, який може копіюватися на сервер при вставці кожної нової рядки. Метод NewGuid формує 16-байтовое двоичное значення за допомогою алгоритму, який забезпечує високу ймовірність того, що жодне з отриманих значень не повторюватиметься. У базі даних SQL Server ідентифікатор GUID зберігається в стовпці uniqueidentifier. який може автоматично створюватися в SQL Server за допомогою функції NEWID () мови Transact-SQL. Використання ідентифікатора GUID в якості первинного ключа може привести до зниження продуктивності. SQL Server забезпечує підтримку функції NEWSEQUENTIALID (). що створює послідовні значення ідентифікатора GUID, глобальна унікальність яких не гарантується, але які можна більш ефективно індексувати.

Поширений сценарій полягає у виклику методу GetChanges об'єкта DataTable для створення копії, яка містить тільки змінилися рядки, після чого ця нова копія використовується при виклику методу Update об'єкта DataAdapter. Це особливо зручно, якщо потрібно упакувати і передати змінилися рядки для окремого компонента, який виконує оновлення. Після поновлення ця копія може містити нові значення ідентифікаторів, які потім повинні бути передані назад в оригінал DataTable для злиття. Причому нові значення ідентифікаторів, цілком ймовірно, будуть відрізнятися від вихідних значень в DataTable. Щоб можна було виконати це злиття, необхідно зберегти початкові значення стовпців AutoIncrement в копії, щоб мати можливість знаходити і оновлювати існуючі рядки в оригіналі DataTable. а не додавати нові рядки, що містять нові значення ідентифікаторів. Однак за замовчуванням ці початкові значення втрачаються після виклику методу Update об'єкта DataAdapter. оскільки для кожної оновлюваної рядки DataRow неявно викликається метод AcceptChanges.

Існує два способи запобігти псуванню значень DataColumn в об'єкті DataRow під час поновлення DataAdapter.

Перший спосіб запобігти псуванню значень полягає в привласненні властивості AcceptChangesDuringUpdate об'єкта DataAdapter значення false. Це впливає на кожен об'єкт DataRow в обновлюваному об'єкті DataTable. За докладнішою інформацією та приклад коду див. Розділ AcceptChangesDuringUpdate.

Другий спосіб передбачає застосування в обробнику подій RowUpdated об'єкта DataAdapter коду, в якому властивості Status присвоюється значення SkipCurrentRow. Значення DataRow оновлюється, але первісне значення кожного об'єкта DataColumn зберігається. Цей спосіб дозволяє зберігати первинні значення одних рядків, але не інших. Наприклад, в коді можна зберегти початкові значення додаються рядків, а не змінних або видаляються рядків шляхом перевірки значення StatementType з подальшим привласненням властивості Status значення SkipCurrentRow тільки для рядків з властивістю StatementType рівним Insert.

Якщо будь-який з цих способів використовується для збереження первинних значень в об'єкті DataRow під час поновлення DataAdapter. то в додатку ADO.NET виконується ряд дій по заміні поточних значень DataRow на нові значення, які повертаються в якості вихідних параметрів або в вигляді першої повертається рядка результуючого набору, зі збереженням початкового значення в кожному DataColumn. Спочатку викликається метод AcceptChanges об'єкта DataRow для збереження поточних значень в якості початкових значень, а потім присвоюються нові значення. Після цього у об'єктів DataRows. у яких властивість RowState одно Added. значення цієї властивості RowState замінюється на Modified. що може не відповідати очікуванням.

Спосіб застосування результатів команди до кожного поновлюваному об'єкту DataRow визначається властивістю UpdatedRowSource кожної команди DbCommand. Це властивість задається рівним одному з значень з перерахування UpdateRowSource.

У наведеній нижче таблиці описуються того, як значення перерахування UpdateRowSource впливають на властивість RowState оновлених рядків.

У цьому розділі представлений зразок, який показує, як отримати значення Autonumber з бази даних Jet 4.0. Ядро бази даних Jet не підтримує виконання декількох інструкцій в пакеті або використання вихідних параметрів, тому використовувати будь-якої з описаних вище методів для повернення нового значення Autonumber. присвоєного вставленої рядку, не можна. Однак в обробник подій RowUpdated можна ввести код, в якому виконується окрема інструкція SELECT @@ IDENTITY для отримання нового значення Autonumber.

Замість додавання відомостей про схему з використанням MissingSchemaAction.AddWithKey в цьому прикладі конфігурація DataTable налаштовується за допомогою правильної схеми до виклику OleDbDataAdapter для заповнення DataTable. В цьому випадку стовпець CategoryID налаштований на зменшення значення в кожній вставляється рядку, починаючи з нуля, шляхом завдання властивості AutoIncrement значення true. властивості AutoIncrementSeed значення 0, а властивості AutoIncrementStep значення -1. Після цього проводиться додавання двох нових рядків і викликається метод GetChanges для додавання змінилися рядків в новий об'єкт DataTable. який переданий методу Update.