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 InsertCommandelementu , UpdateCommandlub 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 DeleteCommandelementów , InsertCommandi 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 DataAdapterprogram DbCommandBuilder automatycznie generuje InsertCommandwłaściwości DataAdapter , UpdateCommandi 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 DataAdapterelementu , 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ę SelectCommandelement , 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ę CommandBuilderRefreshSchema .

Jeśli chcesz wiedzieć, jakie polecenie zostało wygenerowane automatycznie, możesz uzyskać odwołanie do automatycznie wygenerowanych poleceń przy użyciu GetInsertCommandmetod CommandBuilder , GetUpdateCommandi 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");  

Zobacz też