YOUR LOGO ADO.NET - Práca s databázou
YOUR LOGO ADO.NET ADO.NET představuje soubor tříd pro přístup k datům v technologii.NET
YOUR LOGO ADO.NET a.NET Framework Microsoft.NET Framework Common Language Runtime Base Classes Web ServicesUser Interface Data and XML ADO.NET XML...
YOUR LOGO Základní pojmy a architektura Základní jmenné prostory -System.Data – třídy reprezentující obecný přístup k datům, bez ohledu na konktrétní databázi ( DataSet, DataTable, Constraint ) -System.Data.(OleDb|Oracle|SqlClient|Odbc ) – třídy poskytovatelů dat (data providers) -System.Data.Common -System.Data.SqlTypes, System.Data.Sql – specifické třídy pro Microsft SQL Server
YOUR LOGO.NET Data Providers Hierarchie System.Data.OleDb.SqlClient OleDbCommand OleDbConnection OleDbDataReader OleDbDataAdapter SqlCommand SqlConnection SqlDataReader SqlDataAdapter
YOUR LOGO Třídy poskytovatelů dat jsou vždy odvozeny od jedné základní třídy a implementují společné rozhraní podle toho, co mají dělat každá třída má čtyři verze, jejichž jména začínají jménem příslušného poskytovatele dat např. (Sql|OleDB|Oracle|ODBC)Connection implementují rozhraní IDbConnection a dědí od třídy DbConnection, umožňují se připojit k databázi
YOUR LOGO Třídy poskytovatelů
YOUR LOGO Database Connection Connection třídy representující spojení s databází spojení je representována řetězcem (connection string), který se předá konstruktoru nebo nastaví ve vlastnosti ConnectionString příklad řetězce : “server = (local); integrated security = SSPI; database=Northwind” SqlConnection conn= new SqlConnection( "server=localhost;database=mojeDatabaz e;uid=sa;pwd=");
YOUR LOGO Database Connection vlastní spojení se otevře metodou Open spojení je potřeba nakonec zavřít metodou Close, ideální je následující schéma použití : try { using (SqlConnection c = newSqlConnection(s)) { c.Open(); … ; c.Close() } } catch (SqlException) {…}
YOUR LOGO RECORD SET Record set v ADO.NET neexistuje, existoval v ADO Nahradili ho: -DataReader -DataAdapter -DataSet
YOUR LOGO DataReader Umožňuje použití souboru záznamů, které jsou výsledkem SQL dotazu. Chová se stejně jako forward-only server-side kursor v klasickém ADO
YOUR LOGO Príklad Con.Open(); OleDBCommand = new OleDBCommand(“SELECT * FROM Studenti, con”) OleDBDataReader dtr = cmd.ExecuteReader(); While dtr.Read() { listBox.Items.Add(dtr(“meno”)) } … Con.Close();
YOUR LOGO DataSet a DataAdapter DataSet a DataAdapter, umožňují přenesení dat do lokální cache klienta (tím může být widowsový nebo i webový formulář) a práci s těmito daty i ve stavu, kdy je přerušeno spojení s databází.
YOUR LOGO DataSet DataSet je výsledkem úsilí spojit klasické ADO s XML datovým formátem DataSet je třída, která se nestará o spojení s databází nebo o SQL dotazy. Jedná se o klientský nástroj pro zpracování dat.
YOUR LOGO
Schema objektu dataTable
YOUR LOGO Naplnenie DataSetu Dva spôsoby: -Použití objektu DataAdapter, který vrací výsledek SQL dotazu ve formě XML. -Pracovat přímo s XML. DataSet má metody s jejichž pomocí umí číst a zapisovat XML data a schémata.
YOUR LOGO IDataAdapter
YOUR LOGO DataAdapter adaptér je třída představující spojení do databáze a čtyři příkazy -SelectCommand – slouží k vybrání řádků z databáze -UpdateCommand – ukládání změn v řádcích -InsertCommand – ukládání nových řádků -DeleteCommand – mazání řádků má metody - Fill, která použije SelectCommand k naplnění daty tabulky v DataSet u -Update, která zavolá příslušné příkazy na řádcích, aby se změny projevily v databázi
YOUR LOGO DataAdapter příkazy je možno nastavit ručně nebo pomocí třídy providera CommandBuilder CommandBuilder nastaví ostatní příkazy pomocí již nastaveného SelectCommand u SelectCommand musí vracet alespoň jeden primární klíč nebo alespoň sloupec s UniqueConstraint pokud změníte nějaký parametr SelectCommand u musíte metodou RefreshSchema přegenerovat CommandBuilder metody GetUpdateCommand ap. – vrátí příslušný příkaz
YOUR LOGO Naplenenie cez DataAdapter OleDbConnection con = new OleDbConnection(conStr); OleDbCommand cmd = new OleDbCommand(“SELECT * FROM Studenti”,con); OleDbDataAdapter da = new OleDbDataAdapter(); Da.SelectCommand = cmd; DataSet ds = new DataSet(); da.Fill(ds,”Studenti”);
YOUR LOGO Iná možnosť da.Fill() SqlDataAdapter adapter = new SqlDataAdapter( "select * from zamestnanci", "server=localhost;database=mojeDatabaze;uid=sa;pwd="); DataSet ds = new DataSet(); adapter.Fill(ds,"zamestnanci");
YOUR LOGO Update SqlDataAdapter adapter = new SqlDataAdapter("select * from zamestnanci", "server=localhost;database=mojeDatabaze;uid=sa;pwd="); DataSet ds = new DataSet(); adapter.Fill(ds,"zamestnanci"); SqlCommandBuilder stavitel = new SqlCommandBuilder(adapter); //Vložen í nov é ho ř á dku DataTable tabulka = ds.Tables["zamestnanci"]; DataRow novy_radek = tabulka.NewRow(); novy_radek["jmeno"] = "Jan Okoun"; novy_radek["pozice"] = "sef"; novy_radek["adresa"] = "Nekde 12"; novy_radek["telefon"] = "555685"; novy_radek["plat"] = "45000"; tabulka.Rows.Add(novy_radek); //Postoupen í změněných ř á dek zp á tky do datab á ze adapter.Update(ds);
YOUR LOGO Príklad použitia DataView SqlDataAdapter adapter = new SqlDataAdapter( "select * from zamestnanci", "server=localhost;database=mojeDatabaze;uid=sa;pwd="); DataSetds= new DataSet(); adapter.Fill(ds,"zamestnanci"); DataView pohled = new DataView(ds.Tables["zamestnanci"]); pohled.Sort = "jmeno"; pohled.RowFilter = "plat > 20000"; DataGrid.DataSource = pohled; DataGrid.DataBind(); //podla zmeny pohled.RowStateFilter = DataViewRowState.Deleted;
YOUR LOGO Sql query Sql príkaz: -SELECT * FROM uzivatele WHERE jmeno=’Maurenc’
YOUR LOGO Chybná autentifikace – SQL poison bool OveritUzivatele(string login,string heslo) { SqlConnection prip = new SqlConnection ("server=localhost;database=mojeDatabaze;uid=sa;pwd="); try { prip.Open(); SqlCommand prikaz = new SqlCommand ("SELECT count(*) FROM uzivatele WHERE login='"+login+"'"+ "AND heslo='"+heslo+"'",prip); int pocet = (int)prikaz.ExecuteScalar(); return (pocet > 0); } catch(SqlException) { return false; } finally { prip.Close(); } }
YOUR LOGO Možnosti SQl poisoning SELECT count(*) FROM uzivatele WHERE login='Admin' AND heslo='cokoliv' OR 1=1;--‚ Login: cokoliv Heslo: x'; INSERT INTO uzivatele VALUES('Hacker','heslo');-- Login: cokoliv Heslo: x'; DROP TABLE uzivatele;-- Login: cokoliv Heslo: x'; SHUTDOWN WITH NOWAIT;--
YOUR LOGO Parametrizované príkazy Existujú spôsoby parsovania ako by bolo možné SQL injection predísť Odporučané je ale používať parametrizované príkazy
YOUR LOGO bool OveritUzivatele(string login,string heslo) { SqlConnection prip = new SqlConnection ("server=localhost;database=mojeDatabaze;uid=sa;pwd="); try { prip.Open(); SqlCommand prikaz = new SqlCommand ("SELECT count(*) FROM uzivatele WHERE AND"+ = login; = heslo; int pocet = (int)prikaz.ExecuteScalar(); return (pocet > 0); } catch(SqlException) { return false; } finally { prip.Close(); } }
YOUR LOGO bool OveritUzivatele(string login,string heslo) { OleDbConnection prip = new OleDbConnection ("provider=sqloledb;server=localhost;database="+ "mojeDatabaze;uid=sa;pwd="); try { prip.Open(); OleDbCommand prikaz = new OleDbCommand ("SELECT count(*) FROM uzivatele WHERE login=? AND"+ "heslo=?",prip); = login; = heslo; int pocet = (int)prikaz.ExecuteScalar(); return (pocet > 0); } catch(OleDbException) { return false; } finally { prip.Close(); } }
YOUR LOGO Uložené procedúry CREATE PROCEDURE varchar(30 varchar(30 int OUTPUT AS = count(*) FROM uzivatele WHERE AND GO
YOUR LOGO bool OveritUzivatele(string login,string heslo) { SqlConnection prip = newSqlConnection ("server=localhost;database=mojeDatabaze;uid=sa;pwd="); try { prip.Open(); SqlCommand prikaz = new SqlCommand("proc_OveritUzivatele",prip); prikaz.CommandType = CommandType.StoredProcedure; SqlParameter pocet = prikaz.Parameters.Add pocet.Direction = ParameterDirection.Output; prikaz.ExecuteScalar(); return ((int)pocet.Value > 0); } catch(SqlException) { return false; } finally { prip.Close(); } }