Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
1
ADO .NET
2
Model dostępu do danych za pomocą ADO.NET
3
ADO.NET – ogólna architektura
ADO.NET (ang. ActiveX Data Objects) jest to technologia umożliwiająca dostęp do danych w środowisku .NET, pozwalająca na korzystanie z dowolnego źródła danych bez konieczności ciągłego połączenia z serwerem.. ADO.NET pracuje w trybie bezpołączeniowym, to znaczy nawiązuje połączenie z serwerem i kopiuje dane na lokalny komputer, po czym zamyka to połączenie. Aplikacja może, przez dowolny okres czasu, wprowadzać modyfikacje danych; w momencie, gdy będziemy chcieli zapisać zmiany, ADO.NET nawiąże ponownie połączenie z serwerem i zaktualizuje dane przechowywane w bazie. Źródłem danych może być dowolny magazyn udostępniający dane przez interfejs ODBC lub OLE DB np.: MS SQL Server, Oracle, plik XML itp.
4
Ogólny model dostępu do danych
5
ADO.NET – warstwy dostępu do danych
W aplikacjach korzystających z ADO.NET, pomiędzy aplikacją a bazą danych jest kilka warstw pośredniczących (dostawcy danych, sterowniki, interfejsy). ADO.NET składa się z dwóch podstawowych części: klasy DataSet i innych związanych z nią klas, z zarządzanych dostawców danych (Framework Data Provider), ułatwiających komunikację ze źródłami danych.
6
ADO.NET – ogólna architektura cd.
7
ADO.NET – dostawcy usług dostępu do danych
Dostawca danych to zestaw klas pozwalających na korzystanie z określonego źródła danych. Wśród nich znajdują się cztery podstawowe klasy: Connection - umożliwia nawiązanie połączenia z określonym źródłem danych. Command - wywołuje polecenie na źródle danych; udostępnia kolekcję parametrów (Parameters) i zawsze działa w kontekście otwartego połączenia (Connection) DataAdapter - najbliżej warstwy aplikacji; pobiera dane z określonego źródła i przekazuje je aplikacji w określonej formie; wypełnia obiekt DataSet danymi pochodzącymi ze źródła oraz umożliwia aktualizacje danych w źródle na podstawie DataSet;
8
ADO.NET – dostawcy usług dostępu do danych
DataReader - udostępnia jednokierunkowy strumień danych ze źródła, w trybie „tylko do odczytu”. Może zawierać więcej niż jeden zestaw rekordów - w takim przypadku korzysta się z nich kolejno ADO.NET komunikuje się z bazą za pośrednictwem tzw. Managed Provider – czyli interfejsu dostępowego do konkretnej bazy danych. W zależności od projektowanej aplikacji, użycie konkretnego źródła danych może znacząco wpłynąć na jej jakość. Wybór dostawcy dostępu do danych jest uzależniony od rodzaju baz danych jakich używa dana aplikacja.
9
ADO.NET – dostawcy usług dostępu do danych
Dostawca .NET dla OLE DB (.NET Framework Data Provider for OLE DB) - uzyskuje dostęp do danych za pośrednictwem interfejsu OLE DB. jest dostawcą nadzorowanym, gdyż komunikuje się z interfejsem OLE DB za pośrednictwem klas opakowujących. może korzystać z dowolnej bazy, dla której istnieje sterownik OLE DB (Access, Oracle, SQL Server). klasa realizująca funkcje dostawcy .NET dla OLE DB znajduje się w przestrzeni nazw System.Data.OleDb. stosowany jest dla aplikacji pracujących z wersją Microsoft SQL Server 6.5 i wcześniejszych
10
ADO.NET – dostawcy usług dostępu do danych
Dostawca .NET dla SQL Servera (.NET Framework Provider for SQL Server) charakteryzuje się znacznie lepszą wydajnością niż dostawca ogólnego przeznaczenia, jakim jest OLE DB. nie korzysta z ODBC w czasie połączenia z bazą, dzięki czemu między kodem aplikacji a bazą jest o jedną warstwę mniej. klasa realizująca funkcje dostawcy .NET dla SQL Servera znajduje się w przestrzeni nazw System.Data.SqlClient. stosowany jest dla aplikacji działających z Microsoft SQL Server 7.0 i wersjach wyższych
11
ADO.NET – dostawcy usług dostępu do danych
Dostawca .NET dla ODBC (.NET Framework Data Provider for ODBC) - dla aplikacji używających ODBC. Dostawca .NET dla Oracla (.NET Framework Data Provider for Oracle) - dla Oracle w wersji 8.1 i wyższych. Środowisko ADO.NET zbudowane jest wokół obiektu DataSet.
12
Model klas DataSet Obiekt DataSet jest prostym rezydentnym magazynem danych umożliwiającym przechowywanie dowolnych informacji (np.: części bazy danych) w oderwaniu od źródła. Jest to swego rodzaju lokalna kopia bazy danych lub jej fragmentu. Struktura obiektu DataSet przypomina strukturę bazy danych. Dane w obiekcie DataSet przechowywane są w postaci tabel z danymi, składających się z wierszy i kolumn , Obiekt DataSet pozwala na definiowanie związków pomiędzy tabelami oraz nakładania ograniczeń na dane, a także umożliwia przeszukiwanie i wybieranie określonych rekordów Obiekt DataSet składa się z klas: DataTable, DataRow, DataColumn, DataRelation.
13
Ogólny schemat DataSet
14
Model klas DataSet Obiekt DataSet reprezentuje bufor danych w pamięci i jest podstawowym obiektem przekazywanym pomiędzy warstwą środkową a aplikacją kliencką. Obiekt DataSet obok tabelarycznego widoku danych zorganizowanych w postaci wierszy i kolumn, może przekształcać dane z języka i na język XML. Aplikacja wykorzystująca obiekt DataSet, ma możliwość sortowania, stronicowania, i filtrowania danych, bez potrzeby ich aktualizacji. Klasa DataSet posiada zdefiniowaną właściwość Tables, której wartością jest kolekcja obiektów DataTable (są to tabele zawarte w obiekcie DataSet).
15
Budowa obiektu DataSet
16
Właściwości obiektu DataTable
17
Metody obiektu DataTable
18
Zdarzenia obiektu DataTable
Dla obiektu DataTable możliwe jest wystąpienie następujących zdarzeń: RowChanged – zgłaszane, gdy wiersz został zmieniony. ColumnChanged – zgłaszane, gdy zmieniono wartość w kolumnie. RowDeleted – zgłaszane, gdy wiersz został usunięty.
19
Kolekcja DataRow Klasa DataTable posiada zdefiniowaną właściwość Row, której wartością jest kolekcja obiektów DataRow (są to wiersze zawarte w obiekcie DataTable). Obiekt DataRow reprezentuje jeden wiersz tabeli, przez co umożliwia dodawanie, usuwanie i modyfikację danych, przechowywanych w tabeli, w ograniczeniu tylko do jednego elementu.
20
Właściwości obiektu DataRow
21
Metody obiektu DataRow
22
Kolekcja DataColumn DataTable posiada zdefiniowaną właściwość Columns, której wartością jest kolekcja obiektów DataColumn (są to kolumny zawarte w obiekcie DataTable). Obiekt DataColumn reprezentuje strukturę obiektu DataTable (każda kolumna określa określony typ danych, jakie mogą się w niej znajdować (format i ograniczenia tabeli).
23
Właściwości obiektu DataColumn
24
Metody obiektu DataColumn
25
Wielowersyjność w obiekcie DataSet
Obiekt DataSet przechowuje dwie wersje wszystkich danych, a w czasie edycji wiersza, po wykonaniu metody DataRow.BeginEdit tworzona jest trzecia kopia, zawierająca wszystkie zmiany: zmiany zatwierdzane są metodą DataRow.EndEdit zmiany odrzucane są metodą DataRow.CancelEdit. Dane, którymi napełniono obiekt DataSet stanowią wersję oryginalną i służą do stworzenia wersji bieżącej, na której wykonywane są modyfikacje. Przy wykonaniu metody DataSet.AcceptChanges dane z wersji bieżącej przenoszone są do wersji oryginalnej, lub zmiany zostają odrzucone przez wykonanie metody DataSet.RejectChanges.
26
Relacje w obiekcie DataSet
27
Relacje w obiekcie DataSet
Związki pomiędzy tabelami w obiekcie DataSet reprezentowane są przez kolekcję obiektów Relations. Przykładowo, definiowanie związku pomiędzy tabelami: tabela1 i tabela2 w obiekcie DataSet o nazwie ds w języku C# ma postać: ds.Relations.Add("Relacja", ds.Tables("tabela1").Columns("AdresID"), ds.Tables("tabela2").Columns("AdresID"); Najczęstszą metodą tworzenia obiektu DataSet jest wczytanie jego struktury z pliku XML.
28
Tworzenie obiektu DataSet w kodzie programu
W takim wypadku, należy tworzyć obiekt DataSet w kodzie programu, co umożliwia zdefiniowanie jego struktury oraz typu danych, jakich będą używać poszczególne kolumny. Przykładowy kod w języku C#, tworzący obiekt DataSet (ds) o nazwie „Baza”, który będzie zawierał jedną tabelę (dt) o nazwie „dane”. Tabela zawiera dwa wiersze (dr) zawierające zdefiniowane dane. System.Data.DataSet ds = new DataSet("Baza"); System.Data.DataTable dt = new DataTable("dane"); System.Data.DataRow dr;
29
Tworzenie obiektu DataSet w kodzie programu
//Zdefiniowanie struktury tabeli(Columns) i typów wykorzystywanych elementów dt.Columns.Add("ID", Type.GetType("System.Int32")); dt.Columns.Add("Imie" ,Type.GetType("System.String")); dt.Columns.Add("Nazwisko" ,Type.GetType("System.String")); dt.Columns.Add("Adres", Type.GetType("System.String")); //Utworzenie pierwszego wiersza i przypisanie wartości poszczególnym elementom dr=dt.NewRow(); dr["ID"]=1; dr["Imie"] = "Szczepan";
30
Tworzenie obiektu DataSet w kodzie programu
dr["Nazwisko"]="Wozniak"; dr["Adres"] = "Kaszew"; dt.Rows.Add(dr);//dodanie wiersza do tabeli dt //Utworzenie drugiego wiersza i przypisanie wartości poszczególnym elementom dr = dt.NewRow(); dr["ID"]= 2; dr["Imie"] = "Rafał"; dr["Nazwisko"]="Leśniak"; dr["Adres"] = "Turek"; dt.Rows.Add(dr); //dodanie wiersza do tabeli dt ds.Tables.Add(dt); //Zapisanie tabeli w obiekcie DataSet
31
Właściwości klasy DataSet
32
Właściwości klasy DataSet
33
Właściwości klasy DataSet
34
Właściwości klasy DataSet
35
Właściwości klasy DataSet
36
Właściwości klasy DataSet
37
Właściwości klasy DataSet
38
Zdarzenia klasy DataSet
39
Połączenie ze źródłem danych
W ADO.NET połączenie ze źródłem danych realizowane jest to za pomocą klas: DataAdapter, Connection, Command i DataReader, zdefiniowanych dla OLEDB oraz SQL Servera
40
Połączenie ze źródłem danych
Połączenie między obiektem DataSet a źródłem danych umożliwia obiekt DataAdapter. W przypadku, gdy źródłem danych jest dokument XML lub, gdy obiekt DataSet budujemy w kodzie programu obiekt DataAdapter nie jest potrzebny. Obiekt DataAdapter posiada dwie główne metody, są to: Fill – nawiązuje połączenie z bazą danych, wysyła żądanie odczytu ze źródła i umieszcza otrzymane dane w obiekcie DataSet. Update – sprawdza, jakie zmiany nastąpiły w obiekcie DataSet i przesyła elementy, które zostały zmodyfikowane do źródła danych.
41
Połączenie ze źródłem danych
Metody zawarte w DataAdapter dostępne są dla dostawcy: OLEDB w klasie System.Data.OleDb.OleDbDataAdapter SQL Server w klasie System.Data.SqlClient.SqlDataAdapter
42
Model obiektu DataAdapter
Metody Command, obiektu DataAdapter służą do modyfikacji danych w obiekcie DataSet. Kolekcja TableMappings określa sposób odwzorowania w obiektach DataSet tabel i kolumn ze źródła danych.
43
Metody obiektu DataAdapter
Metoda Opis Fill Dodaje lub modyfikuje wiersze w obiekcie DataSet FillSchema Dodaje obiekt DataTable do obiektu DataSet i konfiguruje schemat tabeli GetFillParameters Zwraca tablicę obiektów IDataParameter używanych w poleceniu Select Update Aktualizuje zawartość źródła danych na podstawie informacji zapisanych w obiekcie Dataset, wykorzystując do tego właściwości DeleteCommand, InsertCommand, Update Command
44
Zdarzenie Opis FillError Zdarzenie zachodzi gdy podczas wykonywania metody Fill zostanie zgłoszony błąd. Argumentem jest obiekt FillErrorEventArgs. RowUpdated Zachodzi w trakcie wykonywania metody Update, po wykonaniu polecenia UPDATE. Argument obsługi jest obiektem klasy RowUpdatedEventArgs, która udostępnia właściwości: Command – zwraca obiekt Command Errors – zwraca obiekt Exception RecordsAffected – podaje ilość zmodyfikowanych wierszy StatementType – zwraca typ polecenia SQL Row – zwraca obiekt DataRow TableMapping – zwraca obiekt klasy DatatableMapping przesłany z poleceniem SQL RowUpdating Zdarzenie zachodzi podczas wykonywania metody Update, przed wykonaniem polecenia SQL UPDATE. Argument obsługi jest obiektem klasy RowUpdatedEventArgs. Klasa ta udostępnia takie same właściwości jak zdarzenie RowUpdated
45
Zdarzenia obiektu DataAdapter - przykład
string sCnStr = ”northwind"; string sSQL = "select * from customers"; SqlConnection Cn = new SqlConnection(sCnStr); SqlDataAdapter DA = new SqlDataAdapter(sSQL,Cn); // utworzenie uchwytów dla zdarzeń DA.RowUpdating += new SqlRowUpdatingEventHandler(onRowUpdating); DA.RowUpdated += new SqlRowUpdatedEventHandler(onRowUpdated); DA.FillError += new FillErrorEventHandler(FillErrorHandler); DataSet Ds = new DataSet();
46
Zdarzenia obiektu DataAdapter - przykład
//wypełnienie DataSet danymi DA.Fill(Ds,”customers"); //tworzenie nowego wiersza do aktualizacji DataRow DR = Ds.Tables[”customers"].Rows[2]; //uaktualnienie wymaganego wiersza DR["PASSWORD"] = "NET"; //tworzenie obiektu do dynamicznego aktualizowania SqlCommandBuilder Cb = new SqlCommandBuilder(DA); DA.Update(Ds,”customers");
47
Zdarzenia obiektu DataAdapter i ich wykorzystanie cd.
// usunięcie uchwytów do zdarzeń DA.RowUpdating - = new SqlRowUpdatingEventHandler(onRowUpdating); DA.RowUpdated - = new SqlRowUpdatedEventHandler(onRowUpdated); DA.FillError - = new FillErrorEventHandler(FillErrorHandler); DA.Dispose(); Cn.Close();
48
Połączenie z bazą danych
Do połączenia z bazą danych służy obiekt Connection, którego zadaniem jest: nawiązanie połączenia metodą Open( ), kontrolowanie połączenia zamknięcie połączenia pomiędzy aplikacją i bazą danych metodą Close( ). Obiekt Connection jest wykorzystywany przez obiekty DataAdapter i Command w czasie realizacji połączenia. Metody obsługujące obiekt Connection dostępne są dla dostawcy: OLEDB w klasie System.Data.OleDb.OleDbConnection SQL Server w klasie System.Data.SqlClient.SqlConnection
49
Połączenie z bazą danych SQL
Podłączenie do SQL Server za pomocą .NET Framework Provider for SQL Server jest realizowane przez obiekt SqlConnection tworzący połączenie, które zostaje potem otwarte przy pomocy metody Open() SqlConnection con = new SqlConnection("server=localhost; database=Northwind;uid=sa;pwd=;"); con.Open(); Przy tworzeniu wielu połączeń w jednej aplikacji, należy tworzyć pule połączeń, ponieważ pozwalają one zmniejszyć czas dostępu do danych jak i ruch pomiędzy bazą danych a programem z niej korzystającym. Wpływają także w znacznym stopniu na poprawę wydajności, skalowalności i niezawodności aplikacji.
50
Połączenie z bazą danych SQL
W ADO.NET pule połączeń są identyfikowane za pomocą przypisanych im danych konfiguracyjnych (ciąg znaków właściwości ConnectionString dziedziczonej po interfejsie IDbConnection przez wszystkie klasy odpowiedzialne za łączenie z bazami danych). Podczas wywoływania metody Open() klasy SqlConnection specjalny system sprawdza na podstawie wartości właściwości ConnectionString czy istnieje już pula o podanym identyfikatorze. Jeżeli nie ma jeszcze odpowiedniej puli to jest ona tworzona wraz z minimalną wymaganą ilością połączeń i jedno z nich jest oddawane do użytku obiektu, który zgłaszał żądanie.
51
Połączenie z bazą danych SQL
Gdy wszystkie połączenia są już zajęte, tworzone są nowe, aż do górnego limitu ustalonego dla danej puli. Osiągnięcie maksymalnej, dozwolonej ilości wykorzystywanych połączeń w puli skutkuje ustawieniem żądania w kolejce do czasu zwolnienia jakiegoś z istniejących połączeń. Zwolnienie połączenia i zwrócenie go do puli odbywa się po wywołaniu metody Close() lub Dispose() klasy SqlConnection. Jest ono wtedy oznaczane jako nieużywane i czeka w puli na kolejne użycie.
52
Połączenie z bazą danych SQL
SqlConnection connection1 = new SqlConnection(); connection1.ConnectionString="userid=sa;datasource= \"WINDOWSXP\\SQLDB\";persist "+ "security info=False;initial catalog=northwind"; connection1.Open(); // Utworzenie pierwszej puli (A). SqlConnection connection2 = new SqlConnection(); connection2.ConnectionString="userid=sa;datasource= \"WINDOWSXP\\SQLDB\";persist "+ "security info=False;initial catalog=pub"; connection2.Open(); // Utworzenie drugiej puli (B)
53
Połączenie z innymi źródłami danych
W .NET Framework Data Provider for OLE DB połączenie uzyskuje się poprzez obiekt OleDbConnection, OleDbConnection Con = new OleDbConnection("Provider=SQLOLEDB;Data Source=localhost;" + "Integrated Security=SSPI;Initial Catalog=northwind"); nwindConn.Open(); .NET Framework Data Provider for ODBC do tworzenia połaczeń korzysta z OdbcConnection OdbcConnection Con = new OdbcConnection("Driver={SQL Server};Server=localhost;" + "Trusted_Connection=yes;Database=northwind"); Con.Open();
54
Połączenie z innymi źródłami danych
.NET Framework Data Provider for Oracle tworzy połączenie przy pomocy OracleConnection OracleConnection Con=newOracleConnection("Data source=MyOracleServer; Integrated Security=yes;"); nwindConn.Open();
55
Właściwości obiektu Connection
Opis ConnectionString Łańcuch znaków służący do utworzenia połączenia ConnectionTimeout Czas jaki należy oczekiwać na połączenie z bazą danych Database Nazwa bazy danych, z którą należy korzystać po nawiązaniu połączenia DataSource Nazwa bazy danych z jaką, należy nawiązać połączenie Provider Nazwa dostawcy bazy danych State Bieżący stan połączenia
56
Metody obiektu Connection
Metoda Opis BeginTransaction Rozpoczyna transakcję z bazy danych Close Zamyka połączenie z bazą danych Open Otwiera połączenie z bazą danych
57
Wykonywanie instrukcji SQL
Obiekt Command umożliwia wykonanie instrukcji SQL w celu uzyskania kolekcji obiektów spełniających określone kryteria. Obiekt Command umożliwia również wykonanie instrukcji INSERT, DELETE, UPDATE i SELECT. W celu wykonania instrukcji języka SQL należy właściwości CommandText obiektu Command przypisać treść instrukcji. Metody obsługujące obiekt Command dostępne są dla dostawcy: OLEDB w klasie System.Data.OleDb.OleDbCmmand SQL Server w klasie System.Data.SqlClient.SqlCmmand
58
Model obiektu Command
59
Wykonywanie instrukcji SQL
Przykładowo, wykorzystanie obiektu Command dla wykonania instrukcji SELECT w języku C# ma postać: SqlCommand c = new SqlCommand(); // definiowanie obiektu Command c.CommandText = "SELECT*FROM Baza WHERE ID>3” // definiowanie kwerendy wybierającej z tabeli Baza // elementów, których ID>3
60
Wykonywanie instrukcji SQL
Jednym ze sposobów komunikacji z serwerem baz danych jaki udostępnia ADO.NET jest komunikacja pasywna. Do realizacji pasywnej wymiany danych wykorzystywany jest obiekt SqlCommand, który określa parametry komendy przekazywanej serwerowi. Obiekt ten może zadaną komendę wykonać, zwracając zbiór rekordów z bazy danych, wartość skalarną lub pusty zbiór wyników, w zależności od postaci komendy. Zbiór rekordów będących wynikiem działania komendy SQL zostanie zwrócony dzięki metodzie ExecuteReader obiektu SqlCommand; dokładniej mówiąc, wynikiem działania tej metody będzie obiekt typu SqlDataReader, który pozwala na obejrzenie wszystkich wierszy wyniku.
61
Właściwości obiektu Command
Opis CommandText Polecenie SQL CommandType Określa sposób interpretacji polecenia SQL Connection Określa obiekt Connection Parameters Zwraca obiekt ParameterCollection, reprezentujący wszystkie parametry w poleceniu SQL Transaction Obiekt Transaction używany przez Command UpdateRowSource Liczba wierszy objętych poleceniem SQL; w przypadku poprawnego polecenia wartość ta wynosi 1
62
Metody obiektu Command
Metoda Opis Cancel Przerywa wykonanie polecenia CreateParameter Tworzy obiekt Parameter ExecuteNonQuery Wykonuje polecenie SQL, które nie zwraca żadnych danych ExecuteReader Zwraca obiekt DataReader zawierający dane uzyskane w wyniku wykonania polecenia SQL
63
Dostęp do danych Dostęp do danych zapisanych w magazynie danych umożliwia obiekt DataReader , który wyświetla je w postaci strumienia Jest to bardzo szybka metoda dostępu do danych uniemożliwiająca jednak ich modyfikację. Obiekt DataReader: w celu nawiązania połączenia z bazą danych korzysta z obiektu Connection w celu określenia, jakie dane mają być odczytane, korzysta z obiektu Command. Obiekt DataReader nie korzysta a obiektu DataSet, dane wysyłane są bezpośrednio do kontrolek umieszczonych w aplikacji.
64
Dostęp do danych SqlDataReader myReader = myCommand. ExecuteReader();
DataReader umieszcza w pamięci jednorazowo tylko jeden wiersz danych; na żądanie tworzy strumień danych z magazynu danych. Zapobiega to występowaniu wielu problemów związanych z dostępna pamięcią, co daje w wyniku poprawę wydajności systemu. Obiekt ten jest tylko do odczytu, nie można również powracać do rekordów, które zostały już przetworzone. Po zapisaniu danych w obiekcie, aby przejść do kolejnych rekordów należy wywołać metodę Read() . Metoda Read obiektu DataReader powoduje przejście do następnego poprawnego rekordu (o ile taki istnieje).
65
Dostęp do danych Jedno wykonanie metody Read obiektu DataReader, zwraca jeden rekord danych. while(reader.Read()) { myString = reader.Item(0).ToString(); myInt = reader.GetInt32(1); } Metoda Read powoduje przesunięcie wewnętrznego wskaźnika danych do następnego rekordu, nie powodując rzeczywistego odczytu danych. Faktyczny odczyt ma miejsce dopiero po wykonaniu metody GetString lub GetValues.
66
Dostęp do danych Klasa DataReader musi więc posiadać, co najmniej dwa konstruktory, jeden pobierający zestaw wynikowy kwerendy drugi, który dokonuje pobrania obiektu połączenia wykorzystywanego do wykonania polecenia. Metody obsługujące obiekt DataReader dostępne są dla dostawcy: OLEDB w klasie System.Data.OleDb.OleDbDataReader SQL Server w klasie System.Data.SqlClient.SqldataReader
67
Właściwości obiektu DataReader
Opis FieldCount Ilość pól dostępnych w danym rekordzie IsClosed Określa czy obiekt został zamknięty Item Zwraca wartość wybranej kolumny RecordsAffected Okresla ilość wierszy objętych wynikami działania polecenia SQL; w przypadku poprawnego wykonania zwraca 1, w przypadku błędu zwraca -1
68
Metoda Opis Close Zamyka obiekt DataReader GetFieldType (indeks) Zwraca obiekt reprezentujący typ danych wskazanego obiektu GetName (indeks) Zwraca nazwę kolumny GetValue (indeks) Zwraca wartość kolumny w jej oryginalnym formacie GetString (indeks) Zwraca wartość kolumny jako String IsDBNull Metoda stosowana do przedstawiania nieistniejących wartości NextResult W przypadku wykorzystania wyników wsadowego polecenia SQL, metoda ta przesuwa obiekt do następnego rekordu Read Przesuwa obiekt do następnego rekordu
69
Dostęp do danych - przykład
Wykorzystanie obiektów Connection, Command oraz DataReader w celu wyświetlenia informacji o błędnych wierszach zawartych w obiekcie DataAdapter (da), ujawnionych w trakcie próby aktualizacji źródła danych (Update). klasa Connection realizuje połączenie ze źródłem danych. klasa DataReader, odczytuje elementy określone przez klasę Command (za pomocą kwerendy wybiera elementy, w których wystąpił błąd), i zapisuje je do tablicy, która następnie zostanie wyświetlona w postaci kontrolki informacyjnej.
70
Dostęp do danych - przykład
try { da.Update(ds,"Baza"); //aktualizacja źródła obiektu DataAdapter } catch (DBConcurrencyException dbcex) // w przypadku błędu aktualizacji zwracany jest wyjątek { SqlCommand c = new SqlCommand(); // definiowanie obiektu Command c.CommandText = "SELECT*FROM Baza WHERE ID="+dbcex.Row["ID"].ToString(); //konfiguracja wyszukiwana konkretnego elementu w bazie danych
71
Dostęp do danych - przykład
c.Connection = polaczenie; // definiowanie obiektu Connection polaczenie.Open(); // otwarcie połączenia z bazą danych SqlDataReader dr = new SqlDataReader(); // zdefiniowanie obiektu DataReader dr.Read(); // odczytanie rekordu określonego przez kwerendę Object [] rg = new Object[NR_Wiersza]; // utworzenie tablicy dr.GetValues(rg); // zapisanie rekordu w tablicy dr.Close(); // zamknięcie czytnika danych polaczenie.Close(); // zamknięcie połączenia conflict.Display(dbcex.Row, rg); } // wyświetlenie danych w kontrolce użytkownika
72
Wykonywanie operacji SQL nie zwracających danych (INSERT,UPDATE,DELETE)
Ponieważ obiekt DataReader jest tylko do odczytu, więc nie umożliwia modyfikowania danych. Do modyfikacji danych należy użyć instrukcji języka SQL (Update,Insert,Delete ) jako parametru obiektu Command. W celu określenia liczby rekordów, które zostały zmienione należy użyć metody ExecuteNonQuery. int wyswietl = MyCommand.ExecuteNonQuery();
73
Wykonywanie operacji SQL nie zwracających danych (INSERT,UPDATE,DELETE) cd.
Program zwraca numery wierszy dla których zostało wykonane polecenie DELETE. SqlConnection con = new SqlConnection("server=localhost; database=Northwind;uid=sa;pwd=;"); SqlCommand cmd = new SqlCommand(); cmd.CommandText = "DELETE FROM Customers WHERE CustomerName =’ZED'"; cmd.Connection = con; con.Open(); Console.WriteLine(cmd.ExecuteNonQuery().ToString()); con.Close()
74
Model przechwytywania wyjątków – klasa SQL Exception
Obiekty klasy SqlException - opisują błędy zgłaszane przez bazę danych od strony serwera. Błędy mają następujące poziomy istotności: 1-10 to błędy informacyjne które wskazują na pomyłki w danych otrzymanych od użytkownika, 11-16 błędy generowane przez użytkownika które on może poprawić, 17-25 wskazują na błędy oprogramowania lub sprzętu; błędy umożliwiają kontynuowanie pracy natomiast przy 20 i powyżej połączenie SqlConnection zostaje zamknięte.
75
Model przechwytywania wyjątków – klasa SQL Exception
Try { sqlConnection.Open(); sqlInsertCommand.ExecuteNonQuery(); sqlConnection.Close(); MessageBox.Show(”Operacja zakończona sukcesem",”OK",MessageBoxButtons.OK); } catch (SqlException blad) { foreach(SqlError err in blad.Errors) { MessageBox.Show(”Błąd: " + err.Number + " : " err.Message); } } finally { sqlConnection.Close(); }
76
Użycie procedur składowanych,
Procedury składowane umożliwiają zawarcie w jednym rozkazie wielu operacji na bazie danych. Przykładowa procedura bez parametrów ma postać: SqlConnection con = new SqlConnection("server=localhost; database=Northwind;uid=sa;pwd=;"); SqlCommand cmd = new SqlCommand(”Najdrozsze_produkty", con); cmd.CommandType = CommandType.StoredProcedure; con.Open(); SqlDataReader reader = cmd.ExecuteReader(); while(reader.Read()) { Console.WriteLine("{0} - {1:C}", reader.GetString(0),reader.GetDecimal(1)); } con.Close();
77
Użycie procedur składowanych,
Przykładowa procedura z parametrami ma postać: SqlConnection con = new SqlConnection("server=localhost; database=Northwind;uid=sa;pwd=;"); SqlCommand cmd = new SqlCommand (”Najdrozsze_produkty 1", con); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add(new SqlDbType.VarChar, 50)).Value = "USA"; cmd.Parameters.Add(new SqlDbType.Int)); = ParameterDirection.Output; con.Open(); SqlDataReader reader = cmd.ExecuteReader();
78
Użycie procedur składowanych,
Przykładowa procedura z parametrami ma postać (cd) : while(reader.Read()) { Console.WriteLine("{0} - {1}", reader.GetString(0),reader.GetString(1)); } reader.Close(); Console.WriteLine("{0} -1}", con.Close();
79
Procedury parametryczne parametry wejściowe i wyjściowe
Procedura zwraca jako parametr wyjściowy wszystkie rekordy z tabeli Customers w których pole Country jest podane Obiekt Command umożliwia jawne definiowanie parametrów (Parameter) procedury a także dostęp do parametrów wyjściowych i zwracanych wartości. Domyślnie parametry są traktowane jako wejściowe (Input). Aby wyszczególnić typ parametru używa się właściwości ParameterDirection, przy pomocy której można określić czy parametry są InputOutput (wejściowe i wyjściowe), Output (wyjściowe), albo ReturnValue (zwracana wartość).
80
Pobieranie skalarów z baz danych
Do zwrotu pojedynczej wartości z bazy takiej jak np.: wynik operacji Count (*) , służy metoda ExecuteScalar obiektu Command. Zwraca ona wartość skalarną pierwszej kolumny z pierwszego wiersza danych ze zbioru wyników. MyCommand.CommandText = "SELCT COUNT(*) FROM Customers"; int nr_c = (int)myCommand.ExecuteScalar();
81
Transakcje w ADO.NET Do operowania transakcjami w ADO.Net służy klasa System.Data.SqlClient.SqlTransaction. Jest to pewne novum w stosunku do poprzedniej wersji ADO gdzie obiekt transakcji był zawarty w obiekcie połączenia. Przykład otwarcia transakcji: Private dbTemp As New SqlClient.SqlConnection Private trTemp As System.Data.SqlClient.SqlTransaction Private cmdTemp As New SqlClient.SqlCommand Private bTran As Boolean Private Sub btOtwarcie_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btOtwarcie.Click
82
Transakcje w ADO.NET Try // obsługa wyjątków
If Trim(dbTemp.ConnectionString) = "" Then dbTemp.ConnectionString = txtConnStr.Text End If If dbTemp.State = ConnectionState.Closed Then dbTemp.Open() If Not bTran Then // kontrola otwarcia transakcji trTemp = dbTemp.BeginTransaction() bTran = True MsgBox("Transakcja została pomyślnie otwarta!", _ MsgBoxStyle.Information)
83
Transakcje w ADO.NET Catch ex As Exception
MsgBox(ex.ToString, MsgBoxStyle.Exclamation) End Try End Sub Nie można otwierać wielu równoległych lub zagnieżdżonych transakcji. W obiekcie klasy SqlTransaction nie ma żadnego mechanizmu kontrolującego stan transakcji (czy jest już otwarta, zatwierdzona itp.); do tego celu stosowana jest zmienna bTran która pozwala kontrolować otwarcie transakcji.
84
Transakcje w ADO.NET Kod przedstawiający zatwierdzenie otwartej transakcji: Private Sub btCommTran_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles btCommTran.Click Try If Not bTran Then MsgBox("Transakcja nie została otwarta!", _ MsgBoxStyle.Exclamation) Exit Sub End If trTemp.Commit() bTran = False
85
Transakcje w ADO.NET Kod przedstawiający zatwierdzenie otwartej transakcji (c.d.): MsgBox("Transakcja została pomyślnie zatwierdzona!", _ MsgBoxStyle.Information) Catch ex As Exception MsgBox(ex.ToString, MsgBoxStyle.Exclamation) End Try End Sub Do wycofania transakcji wykorzystujemy metodę Rollback : Private Sub btRollTran_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btRollTran.Click
86
Transakcje w ADO.NET Kod przedstawiający wycofanie transakcji (c.d.):
Try If Not bTran Then MsgBox("Transakcja nie jest otwarta!", _ MsgBoxStyle.Exclamation) Exit Sub End If trTemp.Rollback() bTran = False MsgBox("Transakcja została wycofana!", _ MsgBoxStyle.Information)
87
Transakcje w ADO.NET Catch ex As Exception
MsgBox(ex.ToString, MsgBoxStyle.Exclamation) End Try End Sub Pomiędzy otwarciem a zatwierdzeniem transakcji muszą być wykonane jakieś operacje: Private Sub btWykKom_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btWykKom.Click cmdTemp.Connection = dbTemp cmdTemp.Transaction = trTemp cmdTemp.CommandText = txtKom1.Text cmdTemp.ExecuteNonQuery()
88
Transakcje w ADO.NET Transakcję należy „podłączyć” do obiektu typu SqlCommand. W przedstawionych przykładach transakcja została sztucznie rozdzielona na poszczególne etapy; w rzeczywistości wszystko wykonuje się w ramach jednej metody, przy czym wyświetlanie komunikatów po zakończeniu poszczególnych etapów jest niedopuszczalne. Ponieważ transakcja blokuje jedną lub wiele tabel na których wykonywane są operacje, należy przestrzegać następujących zasad: podczas transakcji niedopuszczalna jest żadna interakcja z użytkownikiem,
89
Transakcje w ADO.NET należy wykonywać tylko konieczne w ramach transakcji operacje, należy starać się utrzymywać ustalony porządek w wykonywaniu operacji na wielu tabelach, co pomaga w zapobieganiu tzw. Deadlocków, czyli sytuacji kiedy dwie transakcje blokują sobie nawzajem tabele.
90
Private dbTemp As New SqlClient.SqlConnection
Private trTemp As System.Data.SqlClient.SqlTransaction Private cmdTemp As New SqlClient.SqlCommand Private bTran As Boolean Private Sub btCalTran_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btCalTran.Click Try dbTemp.ConnectionString = txtConnStr.Text dbTemp.Open() trTemp = dbTemp.BeginTransaction() ‘Rozpoczęcie transakcji bTran = True cmdTemp.Connection = dbTemp cmdTemp.Transaction = trTemp cmdTemp.CommandText = txtKom1.Text 'Wykonujemy komendy cmdTemp.ExecuteNonQuery()
91
trTemp.Commit() ‘Zatwierdzenie transakcji
bTran = False dbTemp.Close() MsgBox("Transakcja została wykonana pomyślnie!", _ MsgBoxStyle.Information) Catch ex As Exception If bTran Then ‘Wycofanie transakcji w przypadku błędu trTemp.Rollback() End If MsgBox(ex.ToString, MsgBoxStyle.Exclamation) End Try End Sub
92
Transakcje w ADO.NET Metoda Save obiektu typu SqlTransaction pozwala na zapisanie tzw. punktu zapisu (savepoint), do którego przy wykonywaniu operacji Rollback wycofujemy operacje: Private Sub btSave_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btSave.Click Try trTemp.Save("Punkt zapisu #1") 'Zapisanie punktu zapisu 'Wycofanie do punktu zapisu trTemp.Rollback("Punkt zapisu #1")
93
Transakcje w ADO.NET Właściwość IsolationLevel. obiektu SqlTransaction pozwala ustalić sposób blokowania danych w trakcie transakcji na poziomie połączenia. Zawiera ona następujące elementy: Chaos - nie zatwierdzone zmiany z transakcji o wyższym poziomie IsolationLevel nie mogą być nadpisane, ReadCommitted - współdzielone blokowania są utrzymywane dopóki dane są czytane, przez co unika się tzw. dirty reads czyli czytania zmodyfikowanych przez inną transakcję danych których modyfikacja nie została jeszcze zatwierdzona. Ten sposób blokowania nie zapobiega jednak tzw. non-repeatable reads ani phantom data.
94
Transakcje w ADO.NET ReadUncommitted - przy tym blokowaniu dirty reads jest możliwe. Połączenie nie ustawia żadnych współdzielonych blokowań i ignoruje wyłączne blokowania (exclusive locks). RepeatableRead - ustawiane są blokowania na wszystkich danych które są używane w danej komendzie nie pozwalając na modyfikacje przez innych użytkowników. Zapobiega to tzw. non-repeatable reads czyli sytuacji kiedy transakcja czyta wielokrotnie jakieś dane i pomiędzy tymi odczytami inna transakcja zmodyfikowała te dane. Ten sposób blokowania nie zapobiega jednak tzw. phantom data.
95
Transakcje w ADO.NET Serializable - ustawiane jest na obiekcie typu DataSet zapobiegając modyfikacji i dodawania rekordu do DataSet dopóki transakcja nie jest zatwierdzona. Może zapobiec tzw. phantom data czyli sytuacji kiedy jedna transakcja modyfikuje rekordy z danego zakresu a druga transakcja wprowadza rekord do tego zakresu. Unspecified - inny IsolationLevel niż ten który jest w danej chwili używany, ale który nie może być w tym momencie ustalony. Blokowanie danych w transakcji nie może naruszyć integralności danych.
96
Transakcje w ADO.NET Transakcje są użytecznym elementem biblioteki ADO.Net, jednak należy z nich korzystać tylko w razie konieczności, pamiętając o ograniczeniach które ze sobą niosą. Klasa SqlTransaction nie daje takich możliwości jak transakcje wykonywane na poziomie SQL Serwera, gdyż nie pozwala np.. na stosowanie transakcji zagnieżdżonych. Lepsze efekty można często uzyskać realizując transakcje nie na poziomie ADO.Net, ale w procedurze wsadowej.
97
Zapis i odczyt pól BLOB Binary large objects (BLOBs) mogą zawierać duże ilości danych co uniemożliwia zmieszczenie danych w pojedynczym wierszu który mógłby zostać przetworzony przez DataReader. Problem ten może rozwiązać przeciążona metoda ExecuteReader przyjmująca argument CommandBehavior. SequentialAccess, która modyfikuje zachowanie obiektu DataReader tak że przyjmuje on sekwencyjne dane. Ważna jest kolejność zwracanych pól, ponieważ SequentialAccess modyfikuje DataReader tak aby zwracać dane w kolejności, wobec tego dane raz przeczytane mogą być już niedostępne.
98
Zapis i odczyt pól BLOB SqlConnection con = new SqlConnection("Data Source = localhost;Integrated Security=SSPI; Initial Catalog = test;"); SqlCommand ob = new SqlCommand("SELECT id, obrazek FROM obrazy", con); FileStream fs; BinaryWriter bw;. // zapis obrazka do pliku (*.bmp). // ustawienie rozmiaru bufora int bufferSize = 100; // tablica wypełniana przez GetBytes byte[] outbyte = new byte[bufferSize];
99
Zapis i odczyt pól BLOB // wartości zwrócone prze GetBytes
long retval; // pozycja początkowa na wyjściu BLOB long startIndex = 0; string id = ""; con.Open(); SqlDataReader myReader =ob.ExecuteReader (CommandBehavior.SequentialAccess); while (myReader.Read()) { id = myReader.GetString(0);
100
Zapis i odczyt pól BLOB //utworzenie pliku wyjściowego.
fs = new FileStream(”plik" +id + ".bmp", FileMode.OpenOrCreate, FileAccess.Write); bw = new BinaryWriter(fs); startIndex = 0; // odczyt bajtów i zachowanie ich w outbyte retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize); // dalszy odczyt i zapisywanie danych. while (retval == bufferSize) { bw.Write(outbyte); bw.Flush();
101
Zapis i odczyt pól BLOB startIndex += bufferSize;
retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize); } // zapis reszty do bufora bw.Write(outbyte, 0, (int)retval - 1); bw.Flush(); bw.Close(); // zamkniecie pliku fs.Close(); } myReader.Close(); con.Close();
102
Pozyskiwanie informacji o strukturach danych
Struktura danych włącza bazy danych lub dostępne katalogi z danych źródłowych, tabel i widoków, ograniczenia tabel w bazie danych, itd. Informacje o strukturach danych można uzyskać używając jakiegokolwiek dostawcy danych przy pomocy metody SchemaTable SqlConnection con = new SqlConnection("server=localhost; database=Northwind;uid=sa;pwd=;"); string SQL = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES " + "WHERE TABLE_TYPE = 'BASE TABLE' " + "ORDER BY TABLE_NAME"; SqlDataAdapter schemaDA = new SqlDataAdapter(SQL,con); DataTable schemaTable = new DataTable(); schemaDA.Fill(schemaTable);
103
Pobieranie danych w postaci XML
Dokument XML jest hierarchiczną bazą danych, dlatego też można wczytywać informacje z pliku (lub strumienia) XML do DataSet przy pomocy metody ReadXML(). Metoda ta przyjmuje parametr XmlReadMode, który mówi jak mają być traktowane informacje o strukturze tabeli (Xml Schema), jeśli zawarte są one w dokumencie – dane te opisują tabele znajdujące się w pliku – np. nazwy kolumn, typy danych itp. Obiekt DataSet posiada także możliwość zapisu danych do formatu, XML przy pomocy metody WriteXml(), której parametr określa czy chcemy zapisać wszystkie dane, czy tylko strukturę tabeli (Schema), czy tylko same dane.
104
Pobieranie danych w postaci XML cd.
string xmlDoc version='1.0'?> <books> <book> <title>Przykład odczytu i zapisu XML</title> </book> </books>"; // Załadowanie obiektu StringReader StringReader src = new StringReader(xmlDoc); // Tworzenie nowego obiektu DataSet i odczyt XML DataSet dset = new DataSet(); dset.ReadXml(src); // Zapis DataSet jako nowy plik XML
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.