Download - ADO.NET - Pr áca s databázou
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 Services User 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.SqlClientOleDbCommandOleDbConnectionOleDbDataReaderOleDbDataAdapter
SqlCommandSqlConnectionSqlDataReader
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<provider>Connectiontří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=mojeDatabaze;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
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 DataSetu-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 <provider>CommandBuilder
CommandBuilder nastaví ostatní příkazy pomocí již nastaveného SelectCommandu
SelectCommand musí vracet alespoň jeden primární klíč nebo alespoň sloupec s UniqueConstraint
pokud změníte nějaký parametr SelectCommandu 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 zmenypohled.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: cokolivHeslo: x'; INSERT INTO uzivatele VALUES('Hacker','heslo');--
Login: cokolivHeslo: x'; DROP TABLE uzivatele;--
Login: cokolivHeslo: 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 login=@login AND"+ "heslo=@heslo",prip); prikaz.Parameters.Add("@login",SqlDbType.VarChar); prikaz.Parameters.Add("@heslo",SqlDbType.VarChar);
prikaz.Parameters["@login"].Value = login; prikaz.Parameters["@heslo"].Value = 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); prikaz.Parameters.Add("@login",OleDbType.VarChar); prikaz.Parameters.Add("@heslo",OleDbType.VarChar); prikaz.Parameters["@login"].Value = login; prikaz.Parameters["@heslo"].Value = heslo;
int pocet = (int)prikaz.ExecuteScalar();
return (pocet > 0); } catch(OleDbException) { return false; } finally { prip.Close(); }}
YOUR LOGO
Uložené procedúry
CREATE PROCEDURE proc_OveritUzivatele, @login varchar(30 ), @heslo varchar(30 ), @pocet int OUTPUT AS
SELECT @pocet = count(*) FROM uzivatele WHERE login=@login AND heslo=@hesloGO
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; prikaz.Parameters.Add("@login",login); prikaz.Parameters.Add("@heslo",heslo);
SqlParameter pocet = prikaz.Parameters.Add ("@pocet",SqlDbType.Int); pocet.Direction = ParameterDirection.Output;
prikaz.ExecuteScalar();
return ((int)pocet.Value > 0); } catch(SqlException) { return false; } finally { prip.Close(); }}