Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

1 ADO.NET. 2 Model dostępu do danych za pomocą ADO.NET.

Podobne prezentacje


Prezentacja na temat: "1 ADO.NET. 2 Model dostępu do danych za pomocą ADO.NET."— Zapis prezentacji:

1 1 ADO.NET

2 2 Model dostępu do danych za pomocą ADO.NET

3 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 4 Ogólny model dostępu do danych

5 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 6 ADO.NET – ogólna architektura cd.

7 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 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 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 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 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 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 13 Ogólny schemat DataSet

14 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 15 Budowa obiektu DataSet

16 16 Właściwości obiektu DataTable

17 17 Metody obiektu DataTable

18 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 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 20 Właściwości obiektu DataRow

21 21 Metody obiektu DataRow

22 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 23 Właściwości obiektu DataColumn

24 24 Metody obiektu DataColumn

25 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 26 Relacje w obiekcie DataSet

27 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 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 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 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 31 Właściwości klasy DataSet

32 32 Właściwości klasy DataSet

33 33 Właściwości klasy DataSet

34 34 Właściwości klasy DataSet

35 35 Właściwości klasy DataSet

36 36 Właściwości klasy DataSet

37 37 Właściwości klasy DataSet

38 38 Zdarzenia klasy DataSet

39 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 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 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 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 43 Metody obiektu DataAdapter MetodaOpis FillDodaje lub modyfikuje wiersze w obiekcie DataSet FillSchemaDodaje obiekt DataTable do obiektu DataSet i konfiguruje schemat tabeli GetFillParametersZwraca tablicę obiektów IDataParameter używanych w poleceniu Select UpdateAktualizuje 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 44 ZdarzenieOpis FillErrorZdarzenie zachodzi gdy podczas wykonywania metody Fill zostanie zgłoszony błąd. Argumentem jest obiekt FillErrorEventArgs. RowUpdatedZachodzi 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 RowUpdatingZdarzenie 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 45 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(); Zdarzenia obiektu DataAdapter - przykład

46 46 //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"); Zdarzenia obiektu DataAdapter - przykład

47 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 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 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 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 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 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 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 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 55 Właściwości obiektu Connection WłaściwośćOpis ConnectionStringŁańcuch znaków służący do utworzenia połączenia ConnectionTimeoutCzas jaki należy oczekiwać na połączenie z bazą danych DatabaseNazwa bazy danych, z którą należy korzystać po nawiązaniu połączenia DataSourceNazwa bazy danych z jaką, należy nawiązać połączenie ProviderNazwa dostawcy bazy danych StateBieżący stan połączenia

56 56 Metody obiektu Connection MetodaOpis BeginTransactionRozpoczyna transakcję z bazy danych CloseZamyka połączenie z bazą danych OpenOtwiera połączenie z bazą danych

57 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 58 Model obiektu Command

59 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 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 61 Właściwości obiektu Command WłaściwośćOpis CommandTextPolecenie SQL CommandTypeOkreśla sposób interpretacji polecenia SQL ConnectionOkreśla obiekt Connection ParametersZwraca obiekt ParameterCollection, reprezentujący wszystkie parametry w poleceniu SQL TransactionObiekt Transaction używany przez Command UpdateRowSourceLiczba wierszy objętych poleceniem SQL; w przypadku poprawnego polecenia wartość ta wynosi 1

62 62 Metody obiektu Command MetodaOpis CancelPrzerywa wykonanie polecenia CreateParameterTworzy obiekt Parameter ExecuteNonQueryWykonuje polecenie SQL, które nie zwraca żadnych danych ExecuteReaderZwraca obiekt DataReader zawierający dane uzyskane w wyniku wykonania polecenia SQL

63 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 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 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 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 67 Właściwości obiektu DataReader WłaściwośćOpis FieldCountIlość pól dostępnych w danym rekordzie IsClosedOkreśla czy obiekt został zamknięty ItemZwraca wartość wybranej kolumny RecordsAffectedOkresla ilość wierszy objętych wynikami działania polecenia SQL; w przypadku poprawnego wykonania zwraca 1, w przypadku błędu zwraca -1

68 68 MetodaOpis CloseZamyka 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 IsDBNullMetoda stosowana do przedstawiania nieistniejących wartości NextResultW przypadku wykorzystania wyników wsadowego polecenia SQL, metoda ta przesuwa obiekt do następnego rekordu ReadPrzesuwa obiekt do następnego rekordu

69 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 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 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 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 73 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() Program zwraca numery wierszy dla których zostało wykonane polecenie DELETE. Wykonywanie operacji SQL nie zwracających danych (INSERT,UPDATE,DELETE) cd.

74 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 75 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();} Model przechwytywania wyjątków – klasa SQL Exception

76 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 77 Użycie procedur składowanych, Przykładowa procedura z parametrami ma postać: SqlConnection con = new SqlConnection("server=localhost; database=Northwind;uid=sa;pwd=;"); Najdrozsze_produkty 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 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 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 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 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 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() End If If Not bTran Then // kontrola otwarcia transakcji trTemp = dbTemp.BeginTransaction() bTran = True MsgBox("Transakcja została pomyślnie otwarta!", _ MsgBoxStyle.Information) End If

83 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 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 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 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 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() End Sub

88 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 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 90 Private dbTemp As New SqlClient.SqlConnection Private dbTemp As New SqlClient.SqlConnection Private trTemp As System.Data.SqlClient.SqlTransaction Private trTemp As System.Data.SqlClient.SqlTransaction Private cmdTemp As New SqlClient.SqlCommand Private cmdTemp As New SqlClient.SqlCommand Private bTran As Boolean Private bTran As Boolean Private Sub btCalTran_Click(ByVal sender As System.Object, _ Private Sub btCalTran_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btCalTran.Click ByVal e As System.EventArgs) Handles btCalTran.Click Try Try dbTemp.ConnectionString = txtConnStr.Text dbTemp.ConnectionString = txtConnStr.Text dbTemp.Open() dbTemp.Open() trTemp = dbTemp.BeginTransaction() trTemp = dbTemp.BeginTransaction() Rozpoczęcie transakcji bTran = True bTran = True cmdTemp.Connection = dbTemp cmdTemp.Connection = dbTemp cmdTemp.Transaction = trTemp cmdTemp.Transaction = trTemp cmdTemp.CommandText = txtKom1.Text cmdTemp.CommandText = txtKom1.Text 'Wykonujemy komendycmdTemp.ExecuteNonQuery()

91 91 trTemp.Commit() trTemp.Commit() Zatwierdzenie transakcji bTran = False bTran = False dbTemp.Close() dbTemp.Close() MsgBox("Transakcja została wykonana pomyślnie!", _ MsgBoxStyle.Information) MsgBoxStyle.Information) Catch ex As Exception If bTran Then If bTran Then Wycofanie transakcji w przypadku błędu trTemp.Rollback() trTemp.Rollback() bTran = False bTran = False End If End If MsgBox(ex.ToString, MsgBoxStyle.Exclamation) MsgBox(ex.ToString, MsgBoxStyle.Exclamation) End Try End Try End Sub End Sub

92 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 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 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 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 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 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 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 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 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 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 102 Pozyskiwanie informacji o strukturach danych 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); 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

103 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 104 string xmlDoc Przykład odczytu i zapisu XML "; // 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 Pobieranie danych w postaci XML cd.


Pobierz ppt "1 ADO.NET. 2 Model dostępu do danych za pomocą ADO.NET."

Podobne prezentacje


Reklamy Google