Класс DbCommandBuilder
Класс DbCommandBuilder
предназначен для автоматического генерирования однотабличных SQL-команд, которые позволяют согласовывать изменения, вносимые в объект DataSet
, со связанной с ним БД. Например, если создать экземпляр DbCommandBuilder
и связать его с объектом DbDataAdapter
, то DbCommandBuilder
сгенерирует SQL-запросы на обновление таблицы на основе запроса, указанного в свойстве SelectCommand объекта DbDataAdapter
.
Для генерации запросов UPDATE, INSERT и DELETE методы класса DbCommandBuilder
обращаются к БД за именами базовой таблицы и столбцов, а также о первичных ключах в таблице и в выборке данных из этой таблицы.
SQL-запросы на обновление данных генерируются при выполнении следующих условий:
-
запрос возвращает данные только из одной таблицы (обновляемого представления);
-
в таблице определен первичный ключ;
-
столбец с первичным ключом таблицы входит в выборку данных из этой таблицы.
Первичный ключ гарантирует, что DbCommandBuilder
обновит не более одной записи.
Если свойство SelectCommand задается динамически во время выполнения клиентского приложения, например, при помощи интерактивного запроса, принимающего от пользователя клиентского приложения текстовые команды, то во время работы приложения нельзя задавать соответствующие свойства InsertCommand, UpdateCommand или DeleteCommand. Если объект DataTable
сопоставляется с одной таблицей БД или создается из нее, то можно воспользоваться преимуществом объекта DbCommandBuilder
для автоматического создания запросов DeleteCommand, InsertCommand и UpdateCommand объекта DbDataAdapter
.
Минимальным требованием для работы автоматического создания команд является задание свойства SelectCommand. Схема таблицы, получаемая свойством SelectCommand, определяет синтаксис автоматически созданных инструкций INSERT, UPDATE и DELETE.
Для получения метаданных, необходимых для создания команд INSERT, UPDATE и DELETE, объект DbCommandBuilder
должен выполнить команду SelectCommand
, что приводит к дополнительному взаимодействию с источником данных, а это может снизить производительность клиентского приложения. Если такое положение дел нежелательно, то вместо использования DbCommandBuilder
следует задавать команды манипулирования данными явным образом.
Свойство SelectCommand должно также возвратить, по крайней мере, один столбец первичного ключа или столбец с атрибутом UNIQUE. Если отсутствует и то и другое, то возникнет исключение InvalidOperation и автоматическая генерация команд выполняться не будет.
При наличии связи с DataAdapter
объект DbCommandBuilder
автоматически создает свойства InsertCommand, UpdateCommand и DeleteCommand объекта DataAdapter
, если они являются пустыми ссылками. Если для свойства уже существует значение Command, то оно и используется.
Представления БД, созданные соединением двух или более таблиц, не считаются одной таблицей БД. В данном случае нельзя использовать класс DbCommandBuilder
для автоматического создания команд. Необходимо указывать команды явным образом.
Действия, выполняемые автоматически сконструированными командами, приведены в таблице 31.
Команда | Действия |
---|---|
InsertCommand
|
|
UpdateCommand
|
ПримечаниеДополнительные сведения см. ниже в описании модели оптимистичного параллелизма для обновлений и удалений |
DeleteCommand
|
ПримечаниеДополнительные сведения см. ниже в описании модели оптимистичного параллелизма для обновлений и удалений |
Логика автоматического создания команд для операций UPDATE и DELETE базируется на модели оптимистичного параллелизма, т. е. записи не блокируются для редактирования и могут быть в любое время изменены другими пользователями или процессами. Вследствие того, что запись можно изменить после ее возврата из инструкции SELECT, но до выполнения операции UPDATE или DELETE, то автоматически созданная инструкция UPDATE или DELETE содержит предложение WHERE, указывающее на то, что строка обновляется только в случае наличия в ней всех исходных значений и она не была удалена из источника данных. Это делается во избежание перезаписи новых данных. Когда автоматически созданное обновление пытается обновить строку, которая была удалена или не содержит исходные значения, найденные в DataSet
, команда не изменяет записи и вызывается исключение DBConcurrencyException.
Если требуется выполнить операцию UPDATE или DELETE независимо от исходных значений, необходимо явно задать свойство UpdateCommand для DataAdapter
и не полагаться на автоматическое создание команд.
На автоматическое создание команд накладываются следующие ограничения:
-
в конструируемой команде могут использоваться только несвязанные таблицы. Логика автоматического создания команд для операций INSERT, UPDATE или DELETE предполагает использование изолированных таблиц, не принимая во внимание связи с другими таблицами в источнике данных. В результате при вызове UPDATE для выполнения изменений столбца, участвующего в ограничении внешнего ключа БД, может произойти ошибка. Чтобы избежать её, не следует использовать
DbCommandBuilder
для обновления столбцов, вовлеченных в ограничение внешнего ключа (или в другие ограничения целостности). Вместо этого нужно явно задавать команды, используемые для выполнения операции. -
имена таблиц и столбцов не должны содержать спецсимволов. Логика автоматического создания команд не допускает в именах столбцов или таблиц любых специальных символов, например, пробелов, точек, двойных кавычек или других символов, отличных от алфавитно-цифровых, однако СУБД ЛИНТЕР разрешает спецсимволы внутри двойных кавычек. Поддерживаются указанные полностью имена таблиц в виде catalog.schema.table.
Чтобы автоматически создать команды объекта DataAdapter
, необходимо:
-
установить его свойство SelectCommand;
-
создать объект
CommandBuilder
, указав в аргументе тот объектDataAdapter
, для которого должна автоматически создаваться команда.
При изменении свойства CommandText, принадлежащего свойству SelectCommand, после автоматического создания команд INSERT, UPDATE или DELETE может возникнуть исключение. Например, если измененное свойство SelectCommand.CommandText содержит сведения о схеме, которые не согласованы с используемыми SelectCommand.CommandText сведениями при автоматическом создании команд INSERT, UPDATE или DELETE, то последующие вызовы к методу DataAdapter.Update могут содержать попытки обращения к столбцам, которых больше нет в текущей таблице, на которую ссылается SelectCommand, и в этом случае возникнет исключение.
Для обновления сведений о схеме, используемой CommandBuilder
для автоматического создания команд, следует вызвать метод RefreshSchema
объекта CommandBuilder
.
Чтобы узнать, какая команда была автоматически создана, необходимо с помощью методов GetInsertCommand
, GetUpdateCommand
и GetDeleteCommand
объекта CommandBuilder
получить ссылку на автоматически созданные команды и проверить свойство CommandText, соответствующее команде.
Следующий пример выводит на консоль автоматически созданную команду UPDATE:
Console.WriteLine(builder.GetUpdateCommand().CommandText)
В следующем примере повторно создается таблица AUTO из набора данных autoDS. Метод RefreshSchema
вызывается для внесения новых сведений о столбцах в автоматически созданные команды.
// C# … adapter.SelectCommand.CommandText = "select MAKE, MODEL from SYSTEM.AUTO"; builder.RefreshSchema(); autoDS.Tables.Remove(autoDS.Tables["AUTO"]); adapter.Fill(autoDS, "AUTO");
Конструкторы класса LinterDbCommandBuilder
приведены в таблице 32.
Конструктор | Описание |
---|---|
LinterDbCommandBuilder | Создает новый экземпляр класса LinterDbCommandBuilder. |
LinterDbCommandBuilder(LinterDbDataAdapter) | Создает новый экземпляр класса LinterDbCommandBuilder со связанным с ним объектом LinterDbDataAdapter. |
Свойства класса LinterDbCommandBuilder
приведены в таблице 33.
Свойство | Описание |
---|---|
CatalogLocation | Предоставляет/устанавливает объект CatalogLocation для экземпляра класса DbCommandBuilder. |
CatalogSeparator | Предоставляет/устанавливает символ, который используется в качестве разделителя между идентификатором каталога и остальными идентификаторами. ПримечаниеВ текущей версии ADO.NET-провайдера СУБД ЛИНТЕР данное свойство не поддерживается. |
ConflictOption | Предоставляет/устанавливает значение типа ConflictOption, которое используется объектом DbCommandBuilder. |
DataAdapter | Предоставляет/устанавливает объект DbDataAdapter, который связан с объектом DbCommandBuilder. |
QuotePrefix | Предоставляет/устанавливает начальный символ или символы, используемые для именования объектов БД, имена которых содержат русские буквы или специальные символы. |
QuoteSuffix | Предоставляет/устанавливает конечный символ или символы, используемые для именования объектов БД, имена которых содержат русские буквы или специальные символы. |
SchemaSeparator | Предоставляет или задает строку, которую можно использовать в качестве разделителя имени владельца таблицы и имени таблицы в полной спецификации таблицы. |
SetAllValues | Предоставляет/устанавливает признак, какие значения столбца включены в сгенерированном операторе UPDATE: все или только измененные. |
Методы класса LinterDbCommandBuilder
приведены в таблице 34.
Метод | Описание |
---|---|
DeriveParameters
| Извлекает сведения о параметрах из хранимой процедуры, указанной в объекте LinterDbCommand, и включает их в коллекцию параметров Parameters указанного объекта LinterDbCommand. |
GetDeleteCommand
| Предоставляет автоматически сгенерированный для выполнения операций удаления в БД объект DbCommand. |
GetDeleteCommand(Boolean)
| Предоставляет автоматически сгенерированный для выполнения операций удаления в БД объект DbCommand с заданным правилом именования параметров. |
GetInsertCommand
| Предоставляет автоматически сгенерированный для выполнения операций добавления записей в БД объект DbCommand. |
GetInsertCommand(Boolean)
| Предоставляет автоматически сгенерированный для выполнения операций добавления записей в таблицу БД объект DbCommand с заданным правилом именования параметров. |
GetUpdateCommand
| Предоставляет автоматически сгенерированный для выполнения операции обновления записей в БД объект DbCommand. |
GetUpdateCommand(Boolean)
| Предоставляет автоматически сгенерированный для выполнения операции обновления записи в таблице БД объект DbCommand с заданным правилом именования параметров. |
QuoteIdentifier
| Предоставляет обрамленный прямыми двойными кавычками указанный идентификатор в спецификации объекта БД. |
RefreshSchema
| Обновляет автоматически сгенерированные SQL-операторы, связанные с указанным объектом DbCommandBuilder. |
UnquoteIdentifier
| Предоставляет указанный идентификатор в спецификации объектов БД без обрамляющих его кавычек. |