Opdrachten genereren met CommandBuilders
Wanneer de SelectCommand
eigenschap dynamisch wordt opgegeven tijdens runtime, zoals via een queryprogramma dat een tekstuele opdracht van de gebruiker gebruikt, kunt u mogelijk niet de juiste InsertCommand
, UpdateCommand
of DeleteCommand
tijdens het ontwerptijd opgeven. Als uw DataTable toewijzingen aan of worden gegenereerd op basis van één databasetabel, kunt u profiteren van het DbCommandBuilder object om automatisch de DeleteCommand
, InsertCommand
en UpdateCommand
van de DbDataAdaptertabel te genereren.
Als minimale vereiste moet u de SelectCommand
eigenschap instellen om automatische opdrachtgeneratie te laten werken. Het tabelschema dat door de SelectCommand
eigenschap wordt opgehaald, bepaalt de syntaxis van de automatisch gegenereerde instructies INSERT, UPDATE en DELETE.
De DbCommandBuilder opdracht moet worden SelectCommand
uitgevoerd om de metagegevens te retourneren die nodig zijn om de SQL-opdrachten INSERT, UPDATE en DELETE te maken. Als gevolg hiervan is een extra reis naar de gegevensbron nodig en kan dit de prestaties belemmeren. Als u optimale prestaties wilt bereiken, geeft u uw opdrachten expliciet op in plaats van de DbCommandBuilder.
De SelectCommand
sleutel moet ook ten minste één primaire sleutel of unieke kolom retourneren. Als er geen aanwezig zijn, wordt er een InvalidOperation
uitzondering gegenereerd en worden de opdrachten niet gegenereerd.
Wanneer deze zijn gekoppeld aan eenDataAdapter
, worden de InsertCommand
DbCommandBuilder UpdateCommand
, en DeleteCommand
eigenschappen van de DataAdapter
functie automatisch gegenereerd als ze null-verwijzingen zijn. Als er al een Command
eigenschap bestaat, wordt de bestaande Command
gebruikt.
Databaseweergaven die worden gemaakt door twee of meer tabellen samen te voegen, worden niet beschouwd als één databasetabel. In dit geval kunt u de DbCommandBuilder opdracht niet gebruiken om automatisch opdrachten te genereren. U moet uw opdrachten expliciet opgeven. Zie Gegevensbronnen bijwerken met DataAdapters voor informatie over het expliciet instellen van opdrachten voor het oplossen van updates naar een DataSet
back-up naar de gegevensbron.
Mogelijk wilt u uitvoerparameters weer toewijzen aan de bijgewerkte rij van een DataSet
. Een veelvoorkomende taak is het ophalen van de waarde van een automatisch gegenereerd identiteitsveld of tijdstempel uit de gegevensbron. De DbCommandBuilder uitvoerparameters worden standaard niet toegewezen aan kolommen in een bijgewerkte rij. In dit geval moet u uw opdracht expliciet opgeven. Zie Identiteits- of autonummeringswaarden ophalen voor een voorbeeld van het toewijzen van een automatisch gegenereerd identiteitsveld aan een kolom van een ingevoegde rij.
Regels voor automatisch gegenereerde opdrachten
In de volgende tabel ziet u de regels voor hoe automatisch gegenereerde opdrachten worden gegenereerd.
Opdracht | Regel |
---|---|
InsertCommand |
Hiermee voegt u een rij toe aan de gegevensbron voor alle rijen in de tabel met een RowState van Added. Hiermee worden waarden ingevoegd voor alle kolommen die kunnen worden bijgewerkt (maar niet voor kolommen zoals identiteiten, expressies of tijdstempels). |
UpdateCommand |
Werkt rijen bij in de gegevensbron voor alle rijen in de tabel met een RowState van Modified. Hiermee worden de waarden van alle kolommen bijgewerkt, met uitzondering van kolommen die niet kunnen worden bijgewerkt, zoals identiteiten of expressies. Hiermee worden alle rijen bijgewerkt waarbij de kolomwaarden in de gegevensbron overeenkomen met de primaire-sleutelkolomwaarden van de rij en waar de resterende kolommen in de gegevensbron overeenkomen met de oorspronkelijke waarden van de rij. Zie 'Optimistisch gelijktijdigheidsmodel voor updates en verwijderingen' verderop in dit onderwerp voor meer informatie. |
DeleteCommand |
Hiermee verwijdert u rijen in de gegevensbron voor alle rijen in de tabel met een RowState van Deleted. Hiermee verwijdert u alle rijen waarin de kolomwaarden overeenkomen met de primaire-sleutelkolomwaarden van de rij en waar de resterende kolommen in de gegevensbron overeenkomen met de oorspronkelijke waarden van de rij. Zie 'Optimistisch gelijktijdigheidsmodel voor updates en verwijderingen' verderop in dit onderwerp voor meer informatie. |
Optimistisch gelijktijdigheidsmodel voor updates en verwijderingen
De logica voor het automatisch genereren van opdrachten voor UPDATE- en DELETE-instructies is gebaseerd op optimistische gelijktijdigheid. Records zijn dus niet vergrendeld voor bewerking en kunnen op elk gewenst moment worden gewijzigd door andere gebruikers of processen. Omdat een record kan zijn gewijzigd nadat deze is geretourneerd uit de SELECT-instructie, maar voordat de INSTRUCTIE UPDATE of DELETE wordt uitgegeven, bevat de automatisch gegenereerde INSTRUCTIE UPDATE of DELETE een WHERE-component, waarbij wordt opgegeven dat een rij alleen wordt bijgewerkt als deze alle oorspronkelijke waarden bevat en niet uit de gegevensbron is verwijderd. Dit wordt gedaan om te voorkomen dat nieuwe gegevens worden overschreven. Wanneer een automatisch gegenereerde update probeert een rij bij te werken die is verwijderd of die niet de oorspronkelijke waarden bevat in de DataSet, heeft de opdracht geen invloed op records en wordt er een DBConcurrencyException gegenereerd.
Als u wilt dat de UPDATE of DELETE wordt voltooid, ongeacht de oorspronkelijke waarden, moet u expliciet UpdateCommand
instellen voor het DataAdapter
en niet afhankelijk zijn van het automatisch genereren van opdrachten.
Beperkingen van automatische opdrachtgeneratielogica
De volgende beperkingen gelden voor het automatisch genereren van opdrachten.
Alleen niet-gerelateerde tabellen
Met de logica voor het automatisch genereren van opdrachten worden INSERT-, UPDATE- of DELETE-instructies gegenereerd voor zelfstandige tabellen zonder rekening te houden met relaties met andere tabellen in de gegevensbron. Als gevolg hiervan kan het gebeuren dat er een fout optreedt bij het aanroepen Update
van wijzigingen voor een kolom die deelneemt aan een beperking voor een refererende sleutel in de database. Gebruik de uitzondering niet voor het DbCommandBuilder bijwerken van kolommen die zijn betrokken bij een beperking voor refererende sleutels. Geef in plaats daarvan expliciet de instructies op die worden gebruikt om de bewerking uit te voeren.
Tabel- en kolomnamen
Automatische logica voor het genereren van opdrachten kan mislukken als kolomnamen of tabelnamen speciale tekens bevatten, zoals spaties, punten, aanhalingstekens of andere niet-aanhalingstekens, zelfs als deze worden gescheiden door vierkante haken. Afhankelijk van de provider kan het instellen van de parameters QuotePrefix en QuoteSuffix de generatielogica toestaan om spaties te verwerken, maar er kunnen geen speciale tekens worden ontsnapt. Volledig gekwalificeerde tabelnamen in de vorm van catalog.schema.table worden ondersteund.
De CommandBuilder gebruiken om automatisch een SQL-instructie te genereren
Als u automatisch SQL-instructies voor een wilt DataAdapter
genereren, stelt u eerst de SelectCommand
eigenschap van de DataAdapter
opdracht in, maakt u een CommandBuilder
object en geeft u op als een argument DataAdapter
waarvoor automatisch CommandBuilder
SQL-instructies worden gegenereerd.
' 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 = "]";
De SelectCommand wijzigen
Als u de CommandText
SelectCommand
opdrachten INSERT, UPDATE of DELETE automatisch hebt gegenereerd, kan er een uitzondering optreden. Als de gewijzigde SelectCommand.CommandText
schema-informatie bevat die inconsistent is met de SelectCommand.CommandText
gebruikte opdrachten voor het invoegen, bijwerken of verwijderen van opdrachten automatisch zijn gegenereerd, kunnen toekomstige aanroepen naar de DataAdapter.Update
methode proberen om toegang te krijgen tot kolommen die niet meer voorkomen in de huidige tabel waarnaar wordt verwezen door de SelectCommand
, en er wordt een uitzondering gegenereerd.
U kunt de schemagegevens vernieuwen die worden gebruikt voor het CommandBuilder
automatisch genereren van opdrachten door de RefreshSchema
methode van de CommandBuilder
.
Als u wilt weten welke opdracht automatisch is gegenereerd, kunt u een verwijzing verkrijgen naar de automatisch gegenereerde opdrachten met behulp van de GetInsertCommand
, GetUpdateCommand
en GetDeleteCommand
methoden van het CommandBuilder
object en het controleren van de CommandText
eigenschap van de bijbehorende opdracht.
Het volgende codevoorbeeld schrijft naar de console de updateopdracht die automatisch is gegenereerd.
Console.WriteLine(builder.GetUpdateCommand().CommandText)
Console.WriteLine(builder.GetUpdateCommand().CommandText);
In het volgende voorbeeld wordt de Customers
tabel in de custDS
gegevensset opnieuw gemaakt. De methode RefreshSchema wordt aangeroepen om de automatisch gegenereerde opdrachten met deze nieuwe kolomgegevens te vernieuwen.
' 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");