Udostępnij za pośrednictwem


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żesz nie być w stanie określić odpowiedniego InsertCommand, UpdateCommand lub DeleteCommand w czasie projektowania. Jeśli DataTable odwzorowuje się na lub jest generowane z pojedynczej tabeli bazy danych, możesz skorzystać z obiektu DbCommandBuilder, aby automatycznie wygenerować DeleteCommand, InsertCommand i UpdateCommand dla 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 wykonać SelectCommand w celu zwrócenia metadanych niezbędnych do skonstruowania poleceń SQL INSERT, UPDATE i DELETE. 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 właściwości InsertCommand, UpdateCommand i DeleteCommand elementu DataAdapter, jeśli są one 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ń, aby rozwiązać aktualizacje DataSet do źródła danych, zobacz Aktualizowanie źródeł danych za pomocą elementów DataAdapters.

Możesz zamapować parametry wyjściowe z powrotem do zaktualizowanego wiersza 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ń.

Komenda Reguła
InsertCommand Wstawia wiersz do źródła danych dla wszystkich wierszy w tabeli o wartości RowState i Added. Umieszcza wartości we wszystkich kolumnach, które można zaktualizować, z wyjątkiem kolumn takich jak identyfikatory, wyrażenia czy znaczniki czasu.
UpdateCommand Aktualizuje wiersze w źródle danych dla wszystkich wierszy w tabeli z wartością RowStateModified. Aktualizuje wartości wszystkich kolumn z wyjątkiem kolumn, których nie można zaktualizować, takich jak tożsamości lub wyrażenia. Aktualizuje wszystkie wiersze, 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 aktualizacji i usuwania", w dalszej części tego tematu.
DeleteCommand Usuwa wiersze w źródle danych dla wszystkich wierszy w tabeli z wartością RowStateDeleted. 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 aktualizacji i usuwania", w dalszej części tego tematu.

Optymistyczny model współbieżności dla aktualizacji 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 DataSet, polecenie nie ma wpływu na żadne rekordy, a 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 Update w celu przesł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 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 elementu DataAdapter, najpierw ustaw właściwość SelectCommand dla DataAdapter, a następnie utwórz obiekt CommandBuilder i jako argument podaj DataAdapter, dla którego CommandBuilder automatycznie wygeneruje instrukcje 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 = "]";  

Modyfikowanie polecenia SelectCommand

Jeśli zmodyfikujesz CommandTextSelectCommand 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 DataAdapter.Update mogą próbować uzyskać dostęp do kolumn, które już nie istnieją w bieżącej tabeli, do których odnosi się SelectCommand, i zostanie zgłoszony wyjątek.

Informacje o schemacie używane przez CommandBuilder do automatycznego generowania poleceń można odświeżyć, wywołując metodę RefreshSchema z CommandBuilder.

Jeśli chcesz wiedzieć, jakie polecenie zostało wygenerowane automatycznie, możesz uzyskać odwołanie do automatycznie wygenerowanych poleceń przy użyciu metod GetInsertCommand, GetUpdateCommand i GetDeleteCommand obiektu CommandBuilder i sprawdzając właściwość CommandText 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 odtwarza tabelę Customers w zestawie danych custDS. 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 także