Dela via


Generera kommandon med CommandBuilders

Gäller för: .NET Framework .NET .NET Standard

Ladda ned ADO.NET

SelectCommand När egenskapen för DbDataAdapter objektet anges dynamiskt vid körningstid, till exempel via ett frågeverktyg som tar ett textkommando från användaren, kanske du inte kan ange lämplig InsertCommand, UpdateCommand eller DeleteCommand under designtiden. Om dina DataTable kartor till eller genereras från en enskild databastabell kan du dra nytta av DbCommandBuilder objektet för att automatiskt generera DeleteCommand, InsertCommandoch UpdateCommand av DbDataAdapter.

Anmärkning

I Microsoft SqlClient Data Provider för SQL Server härleds SqlDataAdapter-klassen från DbDataAdapter-klassen och SqlCommandBuilder-klassen härleds från DbCommandBuilder-klassen.

Som minimikrav måste du ange SelectCommand egenskapen för att automatisk kommandogenerering ska fungera. Tabellschemat som hämtas av SelectCommand egenskapen bestämmer syntaxen för de automatiskt genererade INSERT-, UPDATE- och DELETE-uttrycken.

DbCommandBuilder måste utföra SelectCommand för att returnera den metadata som krävs för att konstruera SQL-kommandona INSERT, UPDATE och DELETE. Därför krävs en extra resa till datakällan, vilket kan hindra prestanda. För att uppnå optimal prestanda bör du specificera dina kommandon tydligt istället för att använda DbCommandBuilder.

Anmärkning

SelectCommand Måste också returnera minst en primärnyckel eller unik kolumn. Om inget finns genereras ett InvalidOperation undantag och kommandona genereras inte.

När den är associerad med en DataAdapter genererar DbCommandBuilder automatiskt InsertCommand, UpdateCommand, och DeleteCommand-egenskaperna för DataAdapter om de är null-referenser. Om en Command redan finns för en egenskap används den befintliga Command .

Databasvyer som skapas genom att koppla ihop två eller flera tabeller betraktas inte som en enda databastabell. I det här fallet kan du inte använda DbCommandBuilder för att generera kommandon automatiskt. Du måste uttryckligen ange dina kommandon. Information om hur du uttryckligen anger kommandon för att lösa uppdateringar till en DataSet till datakällan finns i Uppdatera datakällor med DataAdapters.

Du kanske vill mappa utdataparametrar tillbaka till den uppdaterade raden i en DataSet. En vanlig uppgift är att hämta värdet för ett automatiskt genererat identitetsfält eller tidsstämpel från datakällan. DbCommandBuilder mappar inte utdataparametrar till kolumner i en uppdaterad rad som standard. I det här fallet måste du uttryckligen ange kommandot. Ett exempel på att mappa ett automatiskt genererat identitetsfält till en kolumn i en infogad rad finns i Hämta identitets- eller autonummervärden.

Regler för automatiskt genererade kommandon

I följande tabell visas reglerna för hur automatiskt genererade kommandon genereras.

Befallning Regel
InsertCommand Infogar en rad i datakällan för alla rader i tabellen med ett RowStateAdded. Infogar värden för alla kolumner som kan uppdateras (men inte kolumner som identiteter, uttryck eller tidsstämplar).
UpdateCommand Uppdaterar rader i datakällan för alla rader i tabellen där RowState är Modified. Uppdaterar värdena för alla kolumner förutom kolumner som inte kan uppdateras, till exempel identiteter eller uttryck. Uppdaterar alla rader där kolumnvärdena i datakällan matchar primärnyckelkolumnvärdena för raden och där de återstående kolumnerna i datakällan matchar de ursprungliga värdena för raden. Mer information finns i Optimistisk samtidighetsmodell för uppdateringar och borttagningar senare i det här avsnittet.
DeleteCommand Tar bort rader från datakällan för alla rader i tabellen som har RowStateDeleted. Tar bort alla rader där kolumnvärdena matchar primärnyckelkolumnvärdena för raden och där de återstående kolumnerna i datakällan matchar de ursprungliga värdena för raden. Mer information finns i Optimistisk samtidighetsmodell för uppdateringar och borttagningar senare i det här avsnittet.

Optimistisk samtidighetsmodell för uppdateringar och borttagningar

Logiken för att generera kommandon automatiskt för UPDATE- och DELETE-instruktioner baseras på optimistisk samtidighet, dvs. poster är inte låsta för redigering och kan ändras av andra användare eller processer när som helst. Eftersom en post kunde ha ändrats efter att den returnerats från SELECT-instruktionen, men innan instruktionen UPDATE eller DELETE utfärdas, innehåller den automatiskt genererade UPDATE- eller DELETE-instruktionen en WHERE-sats, som anger att en rad endast uppdateras om den innehåller alla ursprungliga värden och inte har tagits bort från datakällan. Detta görs för att undvika att skriva över nya data.

Anmärkning

Om en automatiskt genererad uppdatering försöker uppdatera en rad som har tagits bort eller som inte innehåller de ursprungliga värdena som finns i DataSet, påverkar kommandot inte några poster och en DBConcurrencyException genereras.

Om du vill att UPDATE eller DELETE ska slutföras oavsett ursprungliga värden måste du uttryckligen UpdateCommand ange för DataAdapter och inte förlita dig på automatisk kommandogenerering.

Begränsningar för logik för automatisk kommandogenerering

Följande begränsningar gäller för automatisk kommandogenerering.

Endast orelaterade tabeller

Logiken för automatisk kommandogenerering genererar INSERT-, UPDATE- eller DELETE-instruktioner för fristående tabeller utan att ta hänsyn till några relationer till andra tabeller i datakällan. Därför kan det uppstå ett fel när du anropar Update för att skicka ändringar för en kolumn som deltar i en sekundärnyckelbegränsning i databasen. Undvik det här undantaget genom att inte använda DbCommandBuilder för att uppdatera kolumner som ingår i ett villkor för sekundärnyckel. Ange i stället uttryckligen de instruktioner som används för att utföra åtgärden.

Tabell- och kolumnnamn

Logik för automatisk kommandogenerering kan misslyckas om kolumnnamn eller tabellnamn innehåller specialtecken, till exempel blanksteg, punkter, citattecken eller andra icke-numeriska tecken, även om de avgränsas med hakparenteser. Beroende på leverantören kan inställning av parametrarna QuotePrefix och QuoteSuffix göra det möjligt för genereringslogiken att bearbeta blanksteg, men genereringslogiken kan inte hantera specialtecken. Fullständigt kvalificerade tabellnamn i form av catalog.schema.table stöds.

Använd CommandBuilder för att automatiskt generera en SQL-instruktion

För att automatiskt generera SQL-uttryck för en DataAdapter, ställ först in egenskapen SelectCommand för DataAdapter, och skapa sedan ett CommandBuilder-objekt, där du som argument anger DataAdapter för vilken CommandBuilder ska generera SQL-uttrycken automatiskt.

// Assumes that connection is a valid SqlConnection object  
// inside of a using block. 
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(queryString, connection);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
builder.QuotePrefix = "[";  
builder.QuoteSuffix = "]";  

Modifiera "SelectCommand"

Om du ändrar CommandText av SelectCommand efter att kommandona INSERT, UPDATE eller DELETE har genererats automatiskt kan ett undantag inträffa. Om den ändrade SelectCommand.CommandText innehåller schemainformation som är inkonsekvent med den SelectCommand.CommandText som användes när kommandona infoga, uppdatera eller ta bort genererades automatiskt, kan framtida anrop till DataAdapter.Update metoden försöka komma åt kolumner som inte längre finns i den aktuella tabellen som refereras till av SelectCommand, och ett undantag utlöses.

Du kan uppdatera schemainformationen som används av CommandBuilder för att automatiskt generera kommandon genom att anropa RefreshSchema-metoden för CommandBuilder.

Om du vill veta vilket kommando som genererades automatiskt kan du hämta en referens till de automatiskt genererade kommandona med hjälp av GetInsertCommand, GetUpdateCommand och GetDeleteCommand -metoderna hos CommandBuilder-objektet och kontrollera CommandText-egenskapen för det associerade kommandot.

I följande kodexempel skrivs uppdateringskommandot som genererades automatiskt till konsolen.

// Generate the update command automatically by SqlCommandBuilder
Console.WriteLine(builder.GetUpdateCommand().CommandText);

I följande exempel återskapas tabellen i datamängden. Metoden RefreshSchema anropas för att uppdatera automatiskt genererade kommandon med den här nya kolumninformationen.

// Assumes an open SqlConnection and SqlDataAdapter inside of a using block.
adapter.SelectCommand.CommandText = newQueryString;
builder.RefreshSchema();

dataSet.Tables.Remove(dataSet.Tables[tableName]);
adapter.Fill(dataSet, tableName);

Se även