Wykład 10 Architektura ADO.NET Dostawcy danych Modele dostępu do danych model połączeniowy Model bezpołączeniowy 1
Architektura ADO.NET - zestaw abstrakcyjnych klas, które udostępniają dane z poziomu środowiska.net - dostęp do różnych źródeł danych (relacyjne bazy danych, pliki XML, arkusze kalkulacyjne, pliki tekstowe) - dostęp za pośrednictwem interfejsów API tzw. zarządzanych dostawców danych - dwie metody dostępu do danych: dostęp bezpołączeniowy i połączeniowy. Zestaw klas można uzyskać dostęp do dowolnego źródła danych. Źródło danych traktuje się jako abstrakcyjną encję 2
3
Dostawcy danych (Microsoft u): Odbc OleDb OracleClient SqlClient Aby użyć określonego dostawcy należy w kodzie programu utworzyć obiekty specyficzne dla danego dostawcy np. obiekty połączenia to egzemplarze klas OdbcConnection OleDbConnection OracleConnection SqlConnection Przykład lista zainstalowanych dostawców danych katalog Dostawcy 4
<section name="system.data" type="system.data.common.dbproviderfactoriesconfigurationhandler, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <section name="system.data.dataset" type="system.configuration.namevaluefilesectionhandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" restartonexternalchanges="false" /> <section name="system.data.odbc" type="system.data.common.dbproviderconfigurationhandler, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <section name="system.data.oledb" type="system.data.common.dbproviderconfigurationhandler, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <section name="system.data.oracleclient" type="system.data.common.dbproviderconfigurationhandler, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <section name="system.data.sqlclient" type="system.data.common.dbproviderconfigurationhandler, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 5 Fragment pliku machine.config
Przykład dane dostawców na podstawie pliku machine.config (Dostawcy) 6
// Aplikacja, która wyświetla dane o zainstalowanych w systemie dostawcach using System; using System.Collections.Generic; using System.Text; using System.Data.Common; using System.Data; namespace Dostawcy class Program static void Main(string[] args) DataTable tb = DbProviderFactories.GetFactoryClasses(); // Z fabryki foreach (DataRow drow in tb.rows) StringBuilder sb = new StringBuilder(""); for (int i = 0; i < tb.columns.count; i++) sb.append((i + 1).ToString()).Append("").Append(drow[i].ToString()); sb.append("\n"); Console.WriteLine(sb.ToString()); Console.Read(); 7
Jeżeli aplikacja musi obsługiwać wiele źródeł danych to należy użyć tzw. fabryki klas do dynamicznego tworzenia obiektów wybranego dostawcy. Architektura ADO.NET udostępnia klasę DbProviderFactories do zwracania obiektów wymaganych przez specyficznego dostawcę danych. Do metody GetFactory()tej klasy należy przekazać ciąg znaków z nazwą dostawcy. Metoda ta zwraca obiekt fabryczny, który służy do tworzenia specyficznych obiektów wymaganych przez określonego dostawcę. Przykład dynamicznego ustalania klasy dostawcy i pobierania z fabryki dostawców jego specyficznych obiektów katalog Fabryka_dostawców 8
using System.Collections.Generic; using System.Text; using System.Data.Common; using System.Data; using System; namespace FabrykaDostawcow class Program static void Main(string[] args) DbProviderFactory fabryka; string dostawca = "System.Data.Odbc"; // dostawca danych string polaczenie = "DSN=ASA_Student_10;UID=dba;PWD=sql;"; // pobranie obiektu fabrycznego fabryka = DbProviderFactories.GetFactory(dostawca); // pobranie obiektu polaczenia using (DbConnection conn = fabryka.createconnection()) conn.connectionstring = polaczenie; conn.open(); DbCommand pytanie = fabryka.createcommand(); // polecenie pytanie.commandtext = "SELECT studenci.num_stud, nazwisko, imie, kurs, sekcja FROM studenci " + " key join rejestr WHERE nazwisko = 'Ackwood'"; 9
pytanie.connection = conn; DbDataReader czytacz; czytacz = pytanie.executereader(); czytacz.read(); StringBuilder cr = new StringBuilder(""); cr.append(czytacz["num_stud"].tostring()).append(": NAZWISKO: ").Append(czytacz["nazwisko"].ToString()). Append(" IMIE: ").Append(czytacz["imie"].ToString()).Append(" KURS: "). Append(czytacz["kurs"].ToString()).Append(" GRUPA: ").Append(czytacz["sekcja"].ToString()). Append("\n"); Console.WriteLine(cr.ToString()); conn.close(); Console.Read(); 10
11
Dostęp do danych - model połączeniowy Pomiędzy obiektem DataReader a źródłem danych jest utrzymywane aktywne połączenie. Każde wywołanie metody Read()zwraca wiersz danych ze źródła. Cechą charakterystyczną tego modelu jest fakt, że wczytuje on dane ze zbioru utworzonego za pomocą polecenia SQL owego po jednym rekordzie, sekwenyjnie i tylko w trybie do odczytu. Niemożliwa jest bezpośrednia aktualizacja danych lub ich dodawanie. Relacje pomiędzy klasami DataReader, Command, Connection wyglądają tak jak na rysunku: 12
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data.Common; using System.Data.Odbc; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace WindowsApplication1 public partial class Form1 : Form public Form1() InitializeComponent(); // private void button1_click(object sender, EventArgs e) Application.Exit(); 13
private void butszukaj_click(object sender, EventArgs e) Int32 odnru = Int32.Parse(tbOdNumeru.Text); Int32 donru = Int32.Parse(tbDoNumeru.Text); OdbcConnection polacz = new OdbcConnection("DSN=ASA_Student_10;UID=dba;PWD=sql;"); polacz.open(); String lancuch_polecenia = "select num_stud, nazwisko ' " + " ' imie as nazim, substr(data_ur,1,10) as du " + from studenci where studenci.num_stud between " + ":od_num and :do_num order by num_stud"; OdbcCommand polecenie = new OdbcCommand(); polecenie.connection = polacz; polecenie.commandtext = lancuch_polecenia; polecenie.parameters.addwithvalue("od_num", odnru); polecenie.parameters.addwithvalue("do_num", donru); OdbcDataReader dr = polecenie.executereader(commandbehavior.closeconnection); lbstudenci.visible = true; lbstudenci.items.clear(); while (dr.read()) lbstudenci.items.add(dr["num_stud"].tostring() + ": " + dr["nazim"] + " " + dr["du"]); dr.close(); 14
15
Model bezpołączeniowy Polecenie SQL ładuje dane z zewnętrznego źródła do pamięci podręcznej na maszynie klienta. Program manipuluje zbiorem wynikowym na maszynie lokalnej, a aktualizacje przekazuje z danych w buforze do źródła danych. W modelu tym połączenie jest otwierane tylko na czas wczytania danych ze źródła i dokonania aktualizacji. W ten sposób zostają zwolnione zasoby serwera. 16
Kluczowe składniki modelu bezpołączeniowego to DataAdapter i DataSet. Obiekt DataAdapter pośredniczy w wymianie danych pomiędzy źródłem a buforami klienta. Obiekt DataSet funkcjonuje w pamięci klienta jako relacyjna baza danych i zawiera co najmniej jeden obiekt DataTable. Obiekt DataTable zawiera wiersze i kolumny danych, które pochodzą z tabel w źródłowej bazie danych. Klasa DataAdapter udostępnia takie ważne metody jak Fill() i Update(). Metoda Fill()przekazuje zapytanie do bazy danych i zapisuje zwrócony zbiór w wybranym obiekcie DataTable. Metoda Update()służy do wykonywania operacji wstawiania, aktualizacji i usuwania danych wg zmian dokonanych w obiekcie DataSet Języki... wykład 10 2014-11-07 14:52 17