Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
SelectCommand
Если свойство динамически указывается во время выполнения, например с помощью средства запроса, принимающего текстовую команду от пользователя, возможно, не удается указать соответствующее InsertCommand
UpdateCommand
или DeleteCommand
во время разработки. Если DataTable соответствует или создается из одной таблицы базы данных, вы можете использовать объект DbCommandBuilder для автоматического создания DeleteCommand
, InsertCommand
и UpdateCommand
из DbDataAdapter.
В качестве минимального требования необходимо задать SelectCommand
свойство, чтобы автоматическое создание команд работало. Схема таблицы, полученная свойством SelectCommand
, определяет синтаксис автоматически созданных инструкций INSERT, UPDATE и DELETE.
Элемент DbCommandBuilder должен выполнить SelectCommand
, чтобы вернуть метаданные, необходимые для создания команд INSERT, UPDATE и DELETE SQL. В результате необходимо дополнительное путешествие к источнику данных, и это может препятствовать производительности. Чтобы добиться оптимальной производительности, укажите команды явно, а не с помощью DbCommandBuilder.
Свойство SelectCommand
должно также возвратить по крайней мере один столбец первичного ключа или столбец с атрибутом UNIQUE. Если они отсутствуют, генерируется исключение InvalidOperation
, и команды не создаются.
При сопоставлении с DataAdapter
, объект DbCommandBuilder автоматически генерирует свойства InsertCommand
, UpdateCommand
, и DeleteCommand
для DataAdapter
, если они являются null ссылками. Если Command
объект уже существует для свойства, используется существующий Command
объект.
Представления базы данных, созданные путем объединения двух или более таблиц, не считаются одной таблицей базы данных. В данном случае нельзя использовать DbCommandBuilder для автоматической генерации команд; необходимо явно указать команды. Сведения о явной установке команд для разрешения обновлений обратно в источник данных см. в разделе DataSet
.
Возможно, вам потребуется связать выходные параметры с обновленной строкой DataSet
. Одна из распространенных задач — получение значения автоматически созданного поля удостоверения или метки времени из источника данных. По умолчанию выходные DbCommandBuilder параметры не сопоставляются со столбцами в обновляемой строке. В этом случае необходимо однозначно указать команду. Пример сопоставления автоматически сгенерированного поля идентификатора со столбцом вставленной строки см. в разделе "Получение значений идентификаторов или автонумеров".
Правила для автоматически созданных команд
В следующей таблице показаны правила создания автоматически созданных команд.
командование | Правило |
---|---|
InsertCommand |
Вставляет строку непосредственно в источник данных для всех строк в таблице, имеющих значение RowState равное Added. Вставляет значения для всех столбцов, которые можно изменять (но не для столбцов, таких как идентификаторы, выражения или временные метки). |
UpdateCommand |
Обновляет строки в источнике данных для всех строк в таблице с RowState по Modified. Обновляет значения всех столбцов, кроме тех, которые нельзя обновить, например идентификаторы или выражения. Обновляет все строки, в которых значения столбцов в источнике данных соответствуют значениям столбца первичного ключа строки, а остальные столбцы в источнике данных соответствуют исходным значениям строки. Дополнительные сведения см. в разделе "Модель оптимистического параллелизма для обновлений и удалений", далее в этом разделе. |
DeleteCommand |
Удаляет строки в источнике данных для всех строк в таблице со значением RowState Deleted. Удаляет все строки, в которых значения столбцов соответствуют значениям столбца первичного ключа строки, а остальные столбцы в источнике данных соответствуют исходным значениям строки. Дополнительные сведения см. в разделе "Модель оптимистического параллелизма для обновлений и удалений", далее в этом разделе. |
Оптимистическая модель параллелизма для обновлений и удалений
Логика автоматического создания команд для инструкций UPDATE и DELETE основана на оптимистическом параллелизме, то есть записи не блокируются для редактирования и могут изменяться другими пользователями или процессами в любое время. Так как запись могла быть изменена после возврата из инструкции SELECT, но до выдачи инструкции UPDATE или DELETE автоматически созданная инструкция UPDATE или DELETE содержит предложение WHERE, указывающее, что строка обновляется только в том случае, если она содержит все исходные значения и не была удалена из источника данных. Это делается, чтобы избежать перезаписи новых данных. Когда автоматически созданное обновление пытается обновить строку, которая была удалена или не содержит исходные значения, найденные в DataSet, команда не влияет ни на какие записи, и выбрасывается DBConcurrencyException.
Если требуется, чтобы обновление или удаление выполнялось независимо от исходных значений, необходимо явно задать UpdateCommand
, связанный с DataAdapter
, и не полагаться на автоматическое создание команд.
Ограничения логики автоматического создания команд
Ограничения, которые применяются к автоматической генерации команд, следующие.
Только несвязанные таблицы
Логика автоматического создания команд создает инструкции INSERT, UPDATE или DELETE для автономных таблиц без учета связей с другими таблицами в источнике данных. В результате при вызове Update
отправки изменений для столбца, который участвует в ограничении внешнего ключа в базе данных, может возникнуть сбой. Чтобы избежать этого исключения, не используйте DbCommandBuilder для обновления столбцов, участвующих в ограничении внешнего ключа. Вместо этого явно укажите инструкции, используемые для выполнения операции.
Имена таблиц и столбцов
Логика автоматического создания команд может завершиться ошибкой, если имена столбцов или имена таблиц содержат специальные символы, такие как пробелы, точки, кавычки или другие нефазные символы, даже если они разделены скобками. В зависимости от поставщика настройка параметров QuotePrefix и QuoteSuffix может позволить логике генерации обрабатывать пробелы, но она не может экранировать специальные символы. Поддерживаются полные имена таблиц в форме catalog.schema.table .
Использование CommandBuilder для автоматического создания инструкции SQL
Чтобы автоматически создать инструкции SQL для DataAdapter
, сначала задайте свойство SelectCommand
объекта DataAdapter
, а затем создайте объект CommandBuilder
и укажите в качестве аргумента DataAdapter
, для которого CommandBuilder
автоматически создаст инструкции SQL.
' Assumes that connection is a valid SqlConnection object
' inside of a Using block.
Dim adapter As SqlDataAdapter = New SqlDataAdapter( _
"SELECT * FROM dbo.Customers", connection)
Dim builder As SqlCommandBuilder = New SqlCommandBuilder(adapter)
builder.QuotePrefix = "["
builder.QuoteSuffix = "]"
// Assumes that connection is a valid SqlConnection object
// inside of a using block.
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT * FROM dbo.Customers", connection);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
builder.QuotePrefix = "[";
builder.QuoteSuffix = "]";
Изменение SelectCommand
Если вы измените CommandText
SelectCommand
после автоматического создания команд INSERT, UPDATE или DELETE, может возникнуть исключение. Если изменённый SelectCommand.CommandText
содержит сведения о схеме, которые не согласуются с SelectCommand.CommandText
, используемым при автоматическом создании команд вставки, обновления или удаления, будущие вызовы метода DataAdapter.Update
могут попытаться получить доступ к столбцам, которые больше не существуют в текущей таблице, на которую ссылается SelectCommand
, что приведёт к возбуждению исключения.
Вы можете обновить сведения о схеме, используемые CommandBuilder
для автоматического создания команд, вызвав метод RefreshSchema
объекта CommandBuilder
.
Если вы хотите узнать, какая команда была создана автоматически, вы можете получить ссылку на автоматически созданные команды с помощью GetInsertCommand
GetUpdateCommand
GetDeleteCommand
методов объекта и проверки CommandBuilder
свойства связанной CommandText
команды.
В следующем примере кода записывается в консоль команда обновления, которая была создана автоматически.
Console.WriteLine(builder.GetUpdateCommand().CommandText)
Console.WriteLine(builder.GetUpdateCommand().CommandText);
В следующем примере создается Customers
таблица в наборе custDS
данных. Метод RefreshSchema вызывается для обновления автоматически созданных команд с помощью этой новой информации о столбце.
' Assumes an open SqlConnection and SqlDataAdapter inside of a Using block.
adapter.SelectCommand.CommandText = _
"SELECT CustomerID, ContactName FROM dbo.Customers"
builder.RefreshSchema()
custDS.Tables.Remove(custDS.Tables("Customers"))
adapter.Fill(custDS, "Customers")
// Assumes an open SqlConnection and SqlDataAdapter inside of a using block.
adapter.SelectCommand.CommandText =
"SELECT CustomerID, ContactName FROM dbo.Customers";
builder.RefreshSchema();
custDS.Tables.Remove(custDS.Tables["Customers"]);
adapter.Fill(custDS, "Customers");