
A példa megnyitása előtt hozza létre az InsertTable adatbázist, melyhez a mellékelt InsertTable.sql-t kell lefuttatnia csupán. Az adatbázis MDF, LDF állományai az SQL szerver alapértelmezett mappájában jönnek létre. Szükség esetén módosítsa az InsertTable.sql-ben az elérési útvonalakat.
Az adatbázisban egyetlen tábla kap helyet Table1 névvel, az alábbi oszlopokkal:
- ID - a sorok egyedi azonosításához (identity)
- Value1 - tetszőleges érték tárolásához
- Value2- tetszőleges érték tárolásához
Programból olyan DataTable-t hozunk létre, mely a Value1, Value2 oszlopokat tartalmazza. Az ID megadására nem lesz szükségünk, hiszen az az identity beállítás miatt automatikusan kapja majd az értéket.
Ahhoz, hogy tárolhassunk adatokat, először hozzuk létre azokat:
private void button2_Click(object sender, System.EventArgs e)
{
DataTable dt;
dt = new DataTable("SourceTable");
Készítünk tehát két oszlopot, melyeknek neve, típusa egyezik az adattábla oszlopaival.
dt.Columns.Add("Value1", Type.GetType("System.Int32"));
dt.Columns.Add("Value2", Type.GetType("System.String"));
Ezt követően tetszőleges adatokkal feltöltjük a táblát, majd egy DataGrid-hez kapcsoljuk, hogy látható legyen melyek az új sorok.
DataRow dr;
for (int i=0; i<2; i++)
{
dr = dt.NewRow();
dr["Value1"] = i;
dr["Value2"] = DateTime.Now.ToLongTimeString();
dt.Rows.Add(dr);
}
dataGrid1.DataSource = dt;
Térjük rá most az adattárolásra. Ehhez szükségünk lesz egy kapcsolatra az SQL szerverrel.
A tároláshoz az SqlDataAdapter Update függvényének azon verzióját használjuk fel, melynek paraméterként egy DataTable megadható. Itt fogjuk megadni az imént létrehozott DataTable-t, melynek teljes tartalma bekerül a Table1 táblába.
Ehhez szükségünk lesz tehát egy SqlDataAdapter osztályra. Ennek konstruktorában megadunk egy egyszerű select lekérdezést, melyet a tárolás után a teljes tábla megjelenítéséhez használhatunk fel.
SqlConnection connection = new SqlConnection(connStr);
SqlDataAdapter da = new SqlDataAdapter("select * from Table1", connection);
Következő lépésként szükségünk lesz egy SqlCommandBuilder osztály létrehozására és az SqlDataAdapter-hez való hozzákötésére. Ha ezt nem tennénk, akkor nem jönne létre automatikusan az SqlDataAdapter InsertCommand-ja, mellyel az adattárolást végzi el. Ha kihagynánk az alábbi sort, akkor a tároláskor az „Update requires a valid InsertCommand when passed DataRow collection with new rows” hibaüzenetet kapnánk.
new SqlCommandBuilder(da);
...
A tábla tárolásához most már csak az Update függvény hívása marad hátra.
Hogy az eredmény rögtön látható is legyen, futtatjuk a már megadott select lekérdezést és az eredményt egy másik DataGrid-hez kötjük megjelenítés céljából.
da.Fill(ds);
dataGrid2.DataSource = ds.Tables[0];
connection.Close();
}
Fontos tudnivaló e megoldásnál, hogy az új sorok tárolása csak akkor történik meg helyesen, hogy ha a DataTable-be felvett sorok újak. Új sor esetén a DataRow osztály RowState property-je Added értéket tartalmaz. Ez az az állapot, mikor a fenti kód az elvártaknak megfelelően működik.
Ha a DataTable adatai módosulnak, akkor e módszer nem működik rendeltetésszerűen, mivel ilyenkor a RowState már Modified értéket kap, így a SqlDataAdapter Update függvénye már nem insert into-t akar végrehajtani, hanem az update sql utasítást.
Tudnunk kell azt is, hogy az Update hívása a DataTable sorainak RowState property-jét Unchanged-re változtatja, vagyis kétszer egymás után már nem tudnánk végrehajtani a tárolást.
Ha programunkban biztosítjuk, hogy a tárolandó DataTable sorai mindig Added értékű RowState-el rendelkezzenek, akkor mindig működőképes lesz a fenti kód, mely biztosítja, hogy a DataTable teljes tartalma új soronként hozzáadásra kerüljenek a megadott SQL táblához.