
A példához szükséges a SampleDB adatbázis, melyet a mellékelt Run.cmd BATCH állomány lefuttatásával hozhatunk létre. Csak arra kell ügyelni, hogy a SampleDB.sql parancsállomány a BATCH állománnyal azonos mappában legyen. A SampleDB.sql parancsállomány 5. sorában adja meg helyesen a létrehozandó adatbázisfájlok mappájának nevét és elérési útvonalát.
Áttekintés
A példában egy DataTable objektumba töltjük be a SampleDb adatbázis Table1 táblájának adatait, melyen a Form kontroljainak segítségével műveleteket végezhetünk. Használhatnánk DataSet objektumot is, azonban itt egy táblával dolgozunk, nincs szükség több tábla tárolására. Szükség szerint új rekordokat szúrhatunk be a DataTable objektumba, rekordokat törölhetünk, illetve frissíthetünk a táblában. Az „Adatbázis frissítése” gomb segítségével a DataTable tartalmát egy mozdulattal kiírhatjuk a fizikai adatforrásba.
A DataTable objektumok végső soron cache-ként viselkednek, amelyeknél az adatmódosítás és az adatfrissítés művelete elválik egymástól. A memóriabeli objektumokban tartva és ott szerkesztve adatainkat megtakaríthatjuk az állandó adatbázis-kapcsolat létesítésének, és a DML műveletek elvégzésének idejét.
Adataink frissítése a memóriabeli objektumból a fizikai adattáblába kétlépéses folyamat. Az első lépésben elvégezzük az adatmódosító utasításokat (INSERT/DELETE/UPDATE) a memóriabeli blokkon, majd ezzel az adathalmazzal frissítjük a fizikai adathalmazt. Általában ezt úgy tesszük meg, hogy meghívjuk egy adapter – kapcsolattól függően SqlDataAdapter vagy OleDbDataAdapter - objektum Update metódusát, a megfelelő paraméterrel. Bizonyos beállításokat azonban meg kell tennünk annak érdekében, hogy a frissítés valóban megtörténjen, és az adatok konzisztenciáját megőrizzük. Ezeket a lépéseket ismertetjük a következőkben.
Rekordok beszúrása a DataTable objektumba
A rekordok beszúrásának módja egy új DataRow objektum létrehozása, melynek mezőit feltöltjük a Form-on megadott adatokkal.
DataRow dr = dt.NewRow();
Meghatározzuk az utolsó rekord azonosítóját, majd egy ennél eggyel nagyobb értéket adunk meg az új rekord azonosítójául.
int id = Convert.ToInt32(dt.Rows[dt.Rows.Count-1][0]) + 1;
dr[0] = id;
Végül megadjuk a szövegmezőben megadott karakterláncokat a másik két oszlop adataiként.
dr[1] = textBox1.Text;
dr[2] = textBox2.Text;
dt.Rows.Add(dr);
...
Ekkor tehát egy új rekord került a DataTable objektumba, sajátos állapotjelzővel, melynek értéke fontos lesz az adatfrissítés procedúrájában. Minden rekord rendelkezik egy RowState tulajdonsággal, melynek értéke attól függ, hogy milyen műveletet végeztünk el a rekordon éppen.

RowState
Osztály: DataTable
public DataRowState RowState {get;}
A property értékei egy felsorolt típus elemei, melynek neve DataRowState. Elemei pedig a következők:
| Érték |
Magyarázat |
| Added |
A rekord beszúrásra került a DataTable objektumba, de az AcceptChanges metódus még nem hívódott meg. |
| Deleted |
A rekord törlésre került az objektumból. |
| Detached |
A sor elkészült, de nem lett része a DataRowCollection gyűjteménynek. Ez az állapot köztes állapot a létrehozás és a kollekcióba-sorolás közt. |
| Modified |
A rekord módosult, de az AcceptChanges metódus még nem hívódott meg. |
| Unchanged |
A rekord értékeiben nem történt változás az AcceptChanges meghívása óta. |
A DataTable objektum felhasználásával történő frissítés során minden rekord állapota vizsgálatra kerül, és ahol valamilyen változás történt, ott lefut az adott változást reprezentáló SQL-utasítás, elvégezve a módosítást a fizikai táblán.
Rekordok módosítása
A DataTable objektum rekordjainak módosításakor megvizsgáljuk a rekordokat, megkeressük a megadott azonosítóval rendelkező rekordot, majd módosítjuk a kívánt mezőt.
for(int i=0;i<dt.Rows.Count;i++)
{
if (dt.Rows[i][0].ToString() == comboBox2.Text)
{
Amely mező nem marad üresen az UPDATE fül alatt, az a mező felhasználásra kerül az új érték megadásakor. Amennyiben nem szeretnénk az egyik mezőt módosítani, hagyjuk üresen a szövegdobozt.
if (textBox3.Text != "")
{
dt.Rows[i][1] = textBox3.Text;
textBox3.Text = "";
}
if (textBox4.Text != "")
{
dt.Rows[i][2] = textBox4.Text;
textBox4.Text = "";
}
}
}
Rekordok törlése
A rekordok törlésekor is megkeressük a megadott azonosítóval rendelkező sort, majd az adott rekord Delete metódusával töröljük azt a DataTable objektum gyűjteményéből. A Delete metódust használjuk a RemoveAt metódus helyett, mivel csak ez a metódus törli a rekordot a táblából, és állítja be a RowState tulajdonságot Deleted értékűre. A frissítő metódus ugyanis ezt figyeli, ahogy később látni fogjuk.
for(int i=0;i<dt.Rows.Count;i++)
{
if (dt.Rows[i][0].ToString() == comboBox1.Text)
{
dt.Rows[i].Delete();
}
}
Adatok frissítése
A fizikai adattábla tehát akkor még nem tartalmazza a változásokat. Ennek érdekében létrehozunk egy SqlCommandBuilder objektumot a SqlDataAdapter objektum metódusainak előállításához.
builder = new SqlCommandBuilder(ad);
Nagyon fontos momentum, hogy a SampleDb Table1 oszlopát a megfelelő SQL utasítással hozzuk létre, mert egyébként a SqlCommandBuilder objektum nem ad megfelelő értéket. A lényeg, hogy a tábla tartalmazzon egy elsődleges kulcs oszlopot, melyet az objektum felhasznál az utasítások generálásához.
CREATE TABLE [Table1]
(
[ID] [int] NOT NULL ,
[Name] [varchar] (100) NOT NULL,
[Position] [varchar] (100) NOT NULL,
CONSTRAINT PK_Products PRIMARY KEY CLUSTERED(ID)
) ON [PRIMARY]
GO
A rekordok beszúrásához, frissítéséhez, valamint törléséhez egy-egy SQL-utasításra van szükség. Ezeket a SqlCommandBuilder megfelelő metódusaival generálhatjuk. A generált értékek SqlCommand objektumok, melyeknek CommandText property-je tartalmazza az SQL utasítást.
ad.DeleteCommand = builder.GetDeleteCommand();
ad.InsertCommand = builder.GetInsertCommand();
ad.UpdateCommand = builder.GetUpdateCommand();
Az utasítások közül egy a következőképpen fest:
INSERT INTO TABLE1(ID , NAME , POSITION)
VALUES (@p1, @p2, @p3)
A SqlDataAdapter objektum Update objektumát hívjuk meg ezek után, frissítendő a fizikai adathalmazt.
A frissítést végző gomb lenyomása után a Form negyedik füle alatt megnézhetjük az adattábla pontos tartalmát.