Nyelv

Parancsok létrehozása CommandBuilders használatával

Ha a SelectCommand tulajdonság futásidőben dinamikusan van megadva, például egy olyan lekérdezési eszközzel, amely szöveges parancsot vesz át a felhasználótól, előfordulhat, hogy nem tudja megadni a megfelelőt InsertCommand, UpdateCommandvagy DeleteCommand a tervezéskor. Ha a DataTable egyetlen adatbázistáblára történő leképezéséből vagy annak létrehozásából jön létre, a DbCommandBuilder objektum segítségével automatikusan létrehozhatja a DeleteCommand, InsertCommand, és UpdateCommand az DbDataAdapter-éhez.

Minimális követelményként be kell állítania a tulajdonságot ahhoz, hogy az SelectCommand automatikus parancslétrehozás működjön. A tulajdonság által SelectCommand lekért táblaséma határozza meg az automatikusan létrehozott INSERT, UPDATE és DELETE utasítások szintaxisát.

A DbCommandBuilder-nak végre kell hajtania a SelectCommand-t ahhoz, hogy visszaadja az INSERT, UPDATE és DELETE SQL parancsok létrehozásához szükséges metaadatokat. Ennek eredményeképpen további utazásra van szükség az adatforráshoz, ami akadályozhatja a teljesítményt. Az optimális teljesítmény eléréséhez a parancsokat explicit módon adja meg, ahelyett, hogy a DbCommandBuilder-t használná.

A SelectCommand kulcsnak legalább egy elsődleges kulcsot vagy egyedi oszlopot is vissza kell adnia. Ha egyik sincs jelen, kivétel InvalidOperation keletkezik, és a parancsok nem jönnek létre.

Ha egy DataAdapter társítva van, a DbCommandBuilder automatikusan létrehozza a InsertCommand, UpdateCommand és DeleteCommand tulajdonságokat a DataAdapter esetében, ha azok nullhivatkozások. Ha már létezik egy Command a tulajdonsághoz, a meglévő Command kerül felhasználásra.

A két vagy több tábla összekapcsolásával létrehozott adatbázisnézetek nem tekinthetők egyetlen adatbázistáblának. Ebben az esetben nem használhatja a DbCommandBuilder parancsok automatikus generálására; explicit módon kell megadnia a parancsokat. Az adatforrások frissítéseinek feloldására szolgáló parancsok explicit beállításával kapcsolatos információkért lásd: DataSet.

Előfordulhat, hogy a kimeneti paramétereket vissza szeretné képezni egy frissített sorba DataSet. Az egyik gyakori feladat egy automatikusan létrehozott identitásmező vagy időbélyeg értékének lekérése az adatforrásból. A DbCommandBuilder program alapértelmezés szerint nem rendeli le a kimeneti paramétereket egy frissített sor oszlopaihoz. Ebben az esetben explicit módon kell megadnia a parancsot. Ha példaként szeretné látni, hogyan történik egy automatikusan generált identitásmező visszacsatolása egy beszúrt sor oszlopához, olvassa el az Identitás vagy Autonumber értékek beolvasása című témakört.

Automatikusan létrehozott parancsok szabályai

Az alábbi táblázat az automatikusan létrehozott parancsok létrehozásának szabályait mutatja be.

Parancs Szabály
InsertCommand Beszúr egy sort az adatforrásba a táblázat minden sorára vonatkozóan, amelyek RowState értéke Added. Beszúrja az összes frissíthető oszlop értékeit (de nem az olyan oszlopokat, mint az identitások, kifejezések vagy időbélyegek).
UpdateCommand Frissíti az adatforrás sorait a tábla összes sorában a RowState-val/-vel Modified. Frissíti az összes oszlop értékeit, kivéve a nem frissíthető oszlopokat, például identitásokat vagy kifejezéseket. Frissíti azokat a sorokat, ahol az adatforrás oszlopértékei megegyeznek a sor elsődleges kulcsoszlop-értékeivel, és ahol az adatforrás többi oszlopa megegyezik a sor eredeti értékeivel. További információért lásd a "Frissítések és törlések optimista egyidejűségi modelljét" később a témában.
DeleteCommand Törli az adatforrásból azokat a sorokat, amelyek a táblában vannak, és ahol a RowState értéke Deleted. Törli azokat a sorokat, ahol az oszlopértékek megegyeznek a sor elsődleges kulcs oszlopértékeivel, és ahol az adatforrás többi oszlopa megegyezik a sor eredeti értékével. További információért lásd a "Frissítések és törlések optimista egyidejűségi modelljét" később a témában.

Optimista egyidejűségi modell frissítésekhez és törlésekhez

Az UPDATE és DELETE utasítások parancsainak automatikus generálására szolgáló logika optimista egyidejűségen alapul, vagyis a rekordok nem zárolva vannak szerkesztésre, és más felhasználók vagy folyamatok bármikor módosíthatják őket. Mivel egy rekord a SELECT utasításból való visszaadása után módosítható, de az UPDATE vagy DELETE utasítás kiadása előtt az automatikusan létrehozott UPDATE vagy DELETE utasítás tartalmaz egy WHERE záradékot, amely azt határozza meg, hogy egy sor csak akkor frissül, ha az összes eredeti értéket tartalmazza, és nem törölték az adatforrásból. Ez az új adatok felülírásának elkerülése érdekében történik. Ha egy automatikusan létrehozott frissítés olyan sort próbál frissíteni, amely törölve lett, vagy amely nem tartalmazza a DataSet-ban található eredeti értékeket, a parancs nem érint egyetlen rekordot sem, és egy DBConcurrencyException kivételt vált ki.

Ha azt szeretné, hogy az UPDATE vagy a DELETE az eredeti értékektől függetlenül befejeződjön, kifejezetten be kell állítania a UpdateCommand és a DataAdapter-t, és nem szabad az automatikus parancsgenerálásra támaszkodnia.

Az automatikus parancsgenerálási logika korlátozásai

Az automatikus parancslétrehozásra az alábbi korlátozások vonatkoznak.

Csak nem kapcsolódó táblák

Az automatikus parancsgenerálási logika az önálló táblákHOZ tartozó INSERT, UPDATE vagy DELETE utasításokat hoz létre anélkül, hogy figyelembe veszi az adatforrás más tábláihoz való kapcsolatokat. Ennek eredményeképpen előfordulhat, hogy sikertelen lesz a Update hívása, amikor egy olyan oszlop módosításait próbálja elküldeni, amely részt vesz az adatbázis idegenkulcs-korlátozásában. A kivétel elkerülése érdekében ne használja az DbCommandBuilder idegenkulcs-korlátozásban érintett oszlopok frissítéséhez; ehelyett explicit módon adja meg a művelet végrehajtásához használt utasításokat.

Táblázat- és oszlopnevek

Az automatikus parancsgenerálási logika akkor is meghiúsulhat, ha az oszlopnevek vagy táblázatnevek speciális karaktereket, például szóközöket, pontokat, idézőjeleket vagy egyéb nemnalfanumerikus karaktereket tartalmaznak, még akkor is, ha szögletes zárójelekkel vannak elválasztva. A szolgáltatótól függően előfordulhat, hogy az QuotePrefix és az QuoteSuffix paraméterek beállítása lehetővé teszi a létrehozási logika számára a szóközök feldolgozását, de nem tudja feloldani a speciális karaktereket. A catalog.schema.table formátumú teljes táblanevek használata támogatott.

SQL-utasítás automatikus létrehozása a CommandBuilder használatával

Az SQL-utasítások DataAdapter automatikus létrehozásához először állítsa be a SelectCommand tulajdonságát a DataAdapter objektumnak, majd hozzon létre egy CommandBuilder objektumot, és adja meg argumentumként a DataAdapter objektumot, amelyhez a CommandBuilder automatikusan SQL-utasításokat generál.

' 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 = "]";

A SelectCommand módosítása

Ha az CommandTextSelectCommand parancsokat az INSERT, UPDATE vagy DELETE parancsok automatikus létrehozása után módosítja, kivétel léphet fel. Ha a módosított SelectCommand.CommandText sémaadatok nem összhangban vannak a SelectCommand.CommandText beszúrási, frissítési vagy törlési parancsok automatikus létrehozásakor használt adatokkal, a DataAdapter.Update metódus jövőbeli hívásai megpróbálhatják elérni azokat az oszlopokat, amelyek már nem léteznek az SelectCommandaktuális táblában, és kivételt okoznak.

A sémainformációkat, amelyeket a CommandBuilder parancsok automatikus generálására használ, a RefreshSchemaCommandBuilder metódusának meghívásával frissítheti.

Ha tudni szeretné, hogy melyik parancs lett automatikusan létrehozva, az automatikusan létrehozott parancsra mutató hivatkozást a GetInsertCommand objektum GetUpdateCommand, GetDeleteCommand, és CommandBuilder metódusainak használatával, valamint a társított CommandText parancs tulajdonságának ellenőrzésével szerezheti be.

Az alábbi példakód az automatikusan létrehozott frissítési parancsot írja a konzolra.

Console.WriteLine(builder.GetUpdateCommand().CommandText)
Console.WriteLine(builder.GetUpdateCommand().CommandText);

Az alábbi példa újra létrehozza a Customers táblát az custDS adathalmazban. A RefreshSchema metódus az automatikusan létrehozott parancsok frissítésére szolgál ezzel az új oszlopinformációval.

' 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");

Lásd még