Generowanie poleceń za pomocą CommandBuilders
SelectCommand
Jeśli właściwość jest dynamicznie określona w czasie wykonywania, na przykład za pomocą narzędzia zapytania, które pobiera tekstowe polecenie od użytkownika, może nie być w stanie określić odpowiedniego InsertCommand
elementu , UpdateCommand
lub DeleteCommand
w czasie projektowania. DataTable Jeśli mapy do lub są generowane na podstawie pojedynczej tabeli bazy danych, możesz skorzystać z DbCommandBuilder obiektu w celu automatycznego wygenerowania DeleteCommand
elementów , InsertCommand
i UpdateCommand
DbDataAdapter.
Jako minimalne wymaganie należy ustawić SelectCommand
właściwość, aby automatyczne generowanie poleceń działało. Schemat tabeli pobrany przez SelectCommand
właściwość określa składnię automatycznie generowanych instrukcji INSERT, UPDATE i DELETE.
Element DbCommandBuilder musi zostać wykonany SelectCommand
w celu zwrócenia metadanych niezbędnych do skonstruowania poleceń INSERT, UPDATE i DELETE JĘZYKA SQL. W związku z tym konieczna jest dodatkowa podróż do źródła danych i może to utrudnić wydajność. Aby uzyskać optymalną wydajność, określ polecenia jawnie zamiast używać polecenia DbCommandBuilder.
Element SelectCommand
musi również zwrócić co najmniej jeden klucz podstawowy lub unikatową kolumnę. Jeśli żaden z nich nie istnieje, InvalidOperation
zostanie wygenerowany wyjątek, a polecenia nie zostaną wygenerowane.
Po skojarzeniu z elementem DataAdapter
program DbCommandBuilder automatycznie generuje InsertCommand
właściwości DataAdapter
, UpdateCommand
i DeleteCommand
, jeśli są odwołaniami o wartości null. Command
Jeśli właściwość już istnieje, zostanie użyta istniejącaCommand
.
Widoki bazy danych tworzone przez łączenie dwóch lub większej liczby tabel ze sobą nie są traktowane jako pojedyncza tabela bazy danych. W tym przypadku nie można użyć polecenia DbCommandBuilder do automatycznego generowania poleceń. Musisz jawnie określić polecenia. Aby uzyskać informacje na temat jawnego ustawiania poleceń w celu rozwiązania aktualizacji DataSet
źródła danych, zobacz Aktualizowanie źródeł danych za pomocą elementów DataAdapters.
Możesz zamapować parametry wyjściowe z powrotem na zaktualizowany wiersz elementu DataSet
. Jednym z typowych zadań jest pobieranie wartości pola tożsamości wygenerowanego automatycznie lub sygnatury czasowej ze źródła danych. Parametry DbCommandBuilder wyjściowe nie będą domyślnie mapowane na kolumny w zaktualizowanym wierszu. W tym wystąpieniu należy jawnie określić polecenie. Aby zapoznać się z przykładem mapowania automatycznie wygenerowanego pola tożsamości z powrotem do kolumny wstawionego wiersza, zobacz Pobieranie tożsamości lub wartości autonumerowania.
Reguły dla automatycznie generowanych poleceń
W poniższej tabeli przedstawiono reguły generowania automatycznie generowanych poleceń.
Polecenie | Reguła |
---|---|
InsertCommand |
Wstawia wiersz w źródle danych dla wszystkich wierszy w tabeli z wartością RowState Added. Wstawia wartości dla wszystkich kolumn, które można zaktualizować (ale nie kolumny, takie jak tożsamości, wyrażenia lub znaczniki czasu). |
UpdateCommand |
Aktualizacje wierszy w źródle danych dla wszystkich wierszy w tabeli z wartością RowState Modified. Aktualizacje wartości wszystkich kolumn z wyjątkiem kolumn, które nie są aktualizowane, takie jak tożsamości lub wyrażenia. Aktualizacje wszystkich wierszy, w których wartości kolumn w źródle danych są zgodne z wartościami kolumn klucza podstawowego wiersza, a pozostałe kolumny w źródle danych są zgodne z oryginalnymi wartościami wiersza. Aby uzyskać więcej informacji, zobacz "Optymistyczny model współbieżności dla Aktualizacje i usuwania", w dalszej części tego tematu. |
DeleteCommand |
Usuwa wiersze w źródle danych dla wszystkich wierszy w tabeli z wartością RowState Deleted. Usuwa wszystkie wiersze, w których wartości kolumn są zgodne z wartościami kolumn klucza podstawowego wiersza, a pozostałe kolumny w źródle danych są zgodne z oryginalnymi wartościami wiersza. Aby uzyskać więcej informacji, zobacz "Optymistyczny model współbieżności dla Aktualizacje i usuwania", w dalszej części tego tematu. |
Optymistyczny model współbieżności dla Aktualizacje i usuwania
Logika automatycznego generowania poleceń dla instrukcji UPDATE i DELETE jest oparta na optymistycznej współbieżności — czyli rekordy nie są blokowane do edycji i mogą być modyfikowane przez innych użytkowników lub procesy w dowolnym momencie. Ponieważ rekord mógł zostać zmodyfikowany po powrocie z instrukcji SELECT, ale przed wydaniem instrukcji UPDATE lub DELETE automatycznie wygenerowana instrukcja UPDATE lub DELETE zawiera klauzulę WHERE, określając, że wiersz jest aktualizowany tylko wtedy, gdy zawiera wszystkie oryginalne wartości i nie został usunięty ze źródła danych. Należy to zrobić, aby uniknąć zastępowania nowych danych. Jeśli automatycznie wygenerowana aktualizacja próbuje zaktualizować wiersz, który został usunięty lub który nie zawiera oryginalnych wartości znalezionych w elemecie DataSet, polecenie nie ma wpływu na żadne rekordy i DBConcurrencyException jest zgłaszany.
Jeśli chcesz, aby aktualizacja lub usuwanie zostały ukończone niezależnie od oryginalnych wartości, musisz jawnie ustawić UpdateCommand
dla DataAdapter
elementu i nie polegać na automatycznym generowaniu poleceń.
Ograniczenia logiki automatycznego generowania poleceń
Następujące ograniczenia dotyczą automatycznego generowania poleceń.
Tylko niepowiązane tabele
Logika automatycznego generowania poleceń generuje instrukcje INSERT, UPDATE lub DELETE dla autonomicznych tabel bez uwzględniania relacji z innymi tabelami w źródle danych. W związku z tym może wystąpić błąd podczas wywoływania metody Update
przesyłania zmian dla kolumny, która uczestniczy w ograniczeniu klucza obcego w bazie danych. Aby uniknąć tego wyjątku, nie należy używać DbCommandBuilder elementu do aktualizowania kolumn zaangażowanych w ograniczenie klucza obcego. Zamiast tego należy jawnie określić instrukcje używane do wykonania operacji.
Nazwy tabel i kolumn
Automatyczna logika generowania poleceń może zakończyć się niepowodzeniem, jeśli nazwy kolumn lub nazwy tabel zawierają znaki specjalne, takie jak spacje, kropki, znaki cudzysłowu lub inne znaki niefanumeryczne, nawet jeśli są rozdzielane nawiasami kwadratowymi. W zależności od dostawcy ustawienie parametrów QuotePrefix i QuoteSuffix może zezwalać logiki generowania na przetwarzanie spacji, ale nie może użyć znaków specjalnych. Obsługiwane są w pełni kwalifikowane nazwy tabel w postaci catalog.schema.table .
Używanie programu CommandBuilder do automatycznego generowania instrukcji SQL
Aby automatycznie wygenerować instrukcje SQL dla DataAdapter
elementu , najpierw ustaw SelectCommand
właściwość DataAdapter
, a następnie utwórz CommandBuilder
obiekt i określ jako argument DataAdapter
, dla którego CommandBuilder
instrukcje SQL będą generowane automatycznie.
' 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 = "]";
Modyfikowanie polecenia SelectCommand
Jeśli zmodyfikujesz CommandText
SelectCommand
element po automatycznym wygenerowaniu poleceń INSERT, UPDATE lub DELETE, może wystąpić wyjątek. Jeśli zmodyfikowana SelectCommand.CommandText
zawiera informacje o schemacie, które są niespójne z SelectCommand.CommandText
używanymi podczas automatycznego generowania poleceń wstawiania, aktualizowania lub usuwania, przyszłe wywołania metody mogą próbować uzyskać dostęp do DataAdapter.Update
kolumn, które już nie istnieją w bieżącej tabeli, do których odwołuje się SelectCommand
element , i zostanie zgłoszony wyjątek.
Informacje o schemacie używane przez CommandBuilder
moduł do automatycznego generowania poleceń można odświeżyć, wywołując metodę CommandBuilder
RefreshSchema
.
Jeśli chcesz wiedzieć, jakie polecenie zostało wygenerowane automatycznie, możesz uzyskać odwołanie do automatycznie wygenerowanych poleceń przy użyciu GetInsertCommand
metod CommandBuilder
, GetUpdateCommand
i GetDeleteCommand
obiektu i sprawdzając CommandText
właściwość skojarzonego polecenia.
Poniższy przykład kodu zapisuje w konsoli polecenie aktualizacji, które zostało wygenerowane automatycznie.
Console.WriteLine(builder.GetUpdateCommand().CommandText)
Console.WriteLine(builder.GetUpdateCommand().CommandText);
Poniższy przykład ponownie utworzy tabelę Customers
custDS
w zestawie danych. Metoda RefreshSchema jest wywoływana w celu odświeżenia automatycznie wygenerowanych poleceń przy użyciu tych nowych informacji o kolumnie.
' 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");