PLATFORMY TECHNOLOGICZNE ADO.NET mgr inż. Tomasz Gawron
Architektura ADO.NET Architektura ADO.NET Obiekty DataSet, Connection, Command, DataAdapter i ich współdziałanie Praca w trybie połączonym: DataReader Praca w trybie odłączonym: DataSet Modyfikacje źródła danych Obsługa procedur pamiętanych w b.d. Integracja z XML Transakcje LINQ, Entity Framework ADO.NET Data Services 2 Platformy Technologiczne 2014 Mainframe Directory RDBMS i wiadomości System plików ADO OLE DB XML
Architektura ADO.NET Platformy Technologiczne Database DataSet Tables DataTable DataRowCollection DataColumnCollection ConstraintCollection DataRelationCollection XML.NET Data Provider Connection Transaction Command Parameters DataReader DataAdapter SelectCommand InsertCommand UpdateCommand DeleteCommand ReadXml WriteXml
Tryb połączeniowy Platformy Technologiczne W modelu klient – serwer każdy klient łączy się z bazą podczas startu aplikacji i zwalnia połączenie podczas jej zamykania Serwer musi utrzymywać oddzielne połączenia dla każego klienta Serwery bazodanowe zapewniają dostęp do kursora przechowującego stan aktualnego wiersza –Dostęp do danych –Przesuwanie się przez MoveNext oraz MovePrevious Połączenia busy idle Możliwe niepotrzebne zużycie zasobów Tabele Wyniki zapytania Kursor rs Klient Serwer
Tryb połączeniowy Zalety Połączenie tworzymy tylko raz Możemy ustawiać zmienne powiązane z ‘sesją’ Szeroki dostęp do mechanizmów zabezpieczajacych dostarczonych przez bazę danych Pierwszy wiersz zapytania dostępny od razu Wady Niepotrzebne zużycie zasobów Problemy ze skalowalnością Nie dostosowany do aplikacji webowych Użytkownicy się nie wylogowują Wahająca się liczba użytkowników Nie dostosowany do aplikacji wielowarstwowych 5 Platformy Technologiczne 2014
Tryb bezpołączeniowy Platformy Technologiczne Połączenia są zwalniane zaraz po wykorzystaniu Obiekty danych wykorzystywane są również po zwolnieniu połączenia Połączenie jest nawiązywane by zapisać zmiany do bazy Dane są dostarczane do klienta w jednej operacji Wyniki zapytania przechowywane w pamięci klienta Zasoby serwera są zwalniane Klient zarządza danymi w trybie off-line Ponowne połączenie z bazą by zapisać zmiany Wyniki zapytania Kursor Klient rs Serwer Tabele idle Zasoby są używane tylko gdy są potrzebne Klienci Połączenia Serwer busy idle
Tryb bezpołączeniowy Zalety Mniejsze zużycie zasobów serwera Modyfikacja danych jest szybsza i bardziej elastyczna Dane nie związane z połączeniem Łatwe przekazywanie między warstwami Wykorzystywane w aplikacjach wielowarstwowych oraz webowych Wady Otwieranie i zamykanie połączeń jest kosztowne Wczytywanie dużych ilości danych jest czasochłonne Zużycie zasobów po stronie klienta Mniej opcji zarządzania bezpieczeńswem 7 Platformy Technologiczne 2014
Model obiektowy Platformy Technologiczne Connection Command Parameter DataReader Transaction DataAdapter DataSet DataTable DataColumn DataRow Constraint DataRelation Klasa Opis Connection Umożliwia nawiązanie połączenia z określonym źródłem danych CommandWywołuje polecenie na źródle danych. Udostępnia kolekcję parametrów (Parameters) i zawsze działa w kontekście otwartego połączenia (Connection) DataReader Udostępnia jednokierunkowy (rekord po rekordzie) strumień danych ze źródła, w trybie 'tylko do odczytu' DataAdapterWypełnia DataSet danymi pochodzącymi ze źródła oraz umożliwia aktualizacje danych w źródle na podstawie DataSet-u (kanał łączący obiekt DataSet z dostawcą danych)
Hierarchia klas Platformy Technologiczne Interfejsy IDbConnection IDbCommand IDbTransaction IDataReader Abstrakcyjne klasy bazowe DbConnection DbCommand DbTransaction DbDataReader Implementacja specjalizowana OleDb: implementacja dla OLEDB Sql: implementacja dla SQL Server Oracle: implementacja dla Oracle Odbc: implementacja dla ODBC
Tworzenie połączenia Platformy Technologiczne Łańcuch połączenia (ang. connection string) - ciąg znaków zawierających parametry konfiguracji połączenia Obiekt SqlConnection: Parametry ConnectionString Connection timeout: dopuszczalny czas uzyskania połączenia Data source: nazwa instancji SQL Server lub nazwa komputera Initial catalog: nazwa bazy danych Integrated security; gdy True połączenie z SQL serwerem na podstawie tożsamości konta procesu ASP.NET User ID: konto logowania SQL Server Password: … string strConn = "data source=.;initial catalog=NewDb;integrated security=true"; SqlConnection conn = new SqlConnection(strConn);
Connection String Platformy Technologiczne Umieszczamy w sekcji pliku konfiguracyjnego... < add name=”Northwind” providerName=”System.Data.SqlClient” connectionString=”server=(local); integrated security=SSPI;database=Northwind” / > private DbConnection GetDatabaseConnection ( string name ) { ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings[name]; DbProviderFactory factory = DbProviderFactories.GetFactory(settings.ProviderName ); DbConnection conn = factory.CreateConnection ( ) ; conn.ConnectionString = settings.ConnectionString ; return conn ; }
Obiekt połączenia Platformy Technologiczne public interface IDbConnection { string ConnectionString {get; set;} int ConnectionTimeout {get;} string Database {get;} ConnectionState State {get;} IDbTransaction BeginTransaction(); IDbTransaction BeginTransaction(IsolationLevel il); void ChangeDatabase(string db); void Close(); IDbCommand CreateCommand(); void Open(); } Open, Close – Otwieranie i zamykanie połączenia CreateCommand – Tworzy obiekt Command powiązany z połączeniem ConnectionTimeout – Określenie czasu timeoutu połączenia Database – Nazwa bazy dla połączenia State – Zwraca stan aktualnego połączenia: Broken, Closed, Connecting, Executing, Fetching, or Open. BeginTransaction – Rozpoczyna tranzakcję
Zarządzanie połączeniami Platformy Technologiczne try... catch... finally try { // Open the connection conn.Open(); DoSomething(); } catch ( SqlException ex ) { //Log the exception } finally { conn.Close ( ) ; } Blok using try { using (SqlConnection conn = new SqlConnection(source)) { // Open the connection conn.Open ( ) ; DoSomething(); } catch (SqlException e) { // Log the exception }
Pula połączeń Platformy Technologiczne Connection pooling proces utrzymywania otwartych połączeń i ponownego ich reużycia dla uzytkownika lub kontekstu Parametry ConnectionString dla poolingu Connection Lifetime: długość oczekiwania połączenia na ponowne użycie Max Pool Size: maksymalna liczba połączeń Min Pool Size: Minimalna liczba połączeń Pooling: True/False … cnNorthwind.ConnectionString = _ "Integrated Security=True;" & _ "Initial Catalog=Northwind;" & _ "Data Source=London;" & _ "Pooling=True;" & _ "Min Pool Size=5;" & _ "Connection Lifetime=120;"
Modele programowania Połączeniowy Używa obiektów Command i DataReader DataReader służy do odczytu w przód Zmiany/aktualizacje odbywają się przez obiekt Command Bezpołączeniowy Używa obiektów DataSet do przechowywania danych u klienta DataAdapter obsługuje komunikację miedzy obiektem DataSet a serwerem Obiekty DataSet są niezależne od providera Obiekty DataSet są przechowywane oraz przesyłane przez XML 15 Platformy Technologiczne 2014
Command Platformy Technologiczne public interface IDbCommand { string CommandText {get; set;} int CommandTimeout {get; set;} CommandType CommandType {get; set;} IDbConnection Connection {get; set;} IDbTransaction Transaction {get; set;} UpdateRowSource UpdatedRowSource {get; set;} IDataParameterCollection Parameters {get;} void Cancel(); IDataParameter CreateParameter(); int ExecuteNonQuery(); IDataReader ExecuteReader(); IDataReader ExecuteReader(CommandBehavior cb); object ExecuteScalar(); void Prepare(); // Note ExecuteXmlReader (SqlCommand only) } Connection - referencja do obiektu połączenia CommandType - typ polecenia Text – wyrażenie SQL StoredProcedure CommandText - w zależności od wyboru typu plecenia: Text – treść polecenia SQL StoredProcedure – nazwa procedury Parameters Parametry, z którymi zostanie wykonane zapytanie
Wywołania Command Platformy Technologiczne ExecuteNonQuery Zwraca liczbę wierszy ‘dotkniętych’ przez zapytanie Zapytania DDL and DCL CREATE, ALTER, DROP, GRANT, DENY, REVOKE Zapytania DML INSERT, UPDATE, DELETE ExecuteScalar ExecuteScalar zwraca typ Object ExecuteDataReader Zwraca obiekt DataReader Reader zależny od providera: SqlDataReader, OleDbDataReader DataReader Służy tylko do odczytu, możliwe przesuwanie tylko w przód ExecuteXmlReader ExecuteXmlReader – dostępny tylko dla SQL Server
Command - przykład Platformy Technologiczne private void Demo() { SqlConnection con = new SqlConnection( "Server=localhost; Database=Pubs; Integrated Security=SSPI" ); SqlCommand cmd = new SqlCommand( "SELECT COUNT( * ) FROM Authors", con ); con.Open(); Console.WriteLine( cmd.ExecuteScalar() ); // Writes '23' con.Close(); // Important! }
Asynchroniczne wywołanie Command Platformy Technologiczne IAsyncResult BeginExecuteReader (AsyncCallback callback) IDataReader EndExecuteReader (AsyncResult result) IAsyncResult BeginExecuteNonQuery (AsyncCallback callback) int EndExecuteNonQuery (IAsyncResult result) IAsyncResult BeginExecuteXmlReader (AsyncCallback callback) IDataReader EndExecuteXmlReader (IAsyncResult result)
Zapytania parametryzowane Platformy Technologiczne Command pozwala na definiowanie parametrów wejściowych i wyjściowych Parameter – pola klasy: Name: nazwa parametru Value: wartość parametru DbDataType: typ danych Direction: kierunek parametru Input Output InputOutput ReturnValue
Zapytania parametryzowane - przykład Platformy Technologiczne Zdefiniowanie zapytania SQL Server: Identyfikacja parametru przez SqlCommand cmd = new SqlCommand(); cmd.CommandText = "DELETE FROM Empls WHERE EmployeeID 2.Dodanie parametru cmd.Parameters.Add( new OleDbType.BigInt)); 3.Przypisanie wartości = 1234; cmd.ExecuteNonQuery();
Data Reader Platformy Technologiczne Służy do odczytu strumienia danych zwróconych przez zapytanie Tylko do odczytu w przód Szybki dostęp Praca w trybie połączeniowym Programista zarządza połączeniem i danymi Małe zużycie zasobów public interface IDataReader { int Depth {get;} bool IsClosed {get;} int RecordsAffected {get;} … void Close(); DataTable GetSchemaTable(); bool NextResult(); bool Read(); … }
Data Reader Platformy Technologiczne object[ ] dataRow = new object[reader.FieldCount]; int cols = reader.GetValues(dataRow); Przeczytaj kolumny do tablicy object val0 = reader[0]; object nameVal = reader["LastName"]; Odczyt za pomocą indekserów string firstName = reader.getString(2); Odczyt za pomocą metod } reader.Close(); Zamknięcie obiektu IDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { Stwórz obiekt i rozpocznij odczyt
Data Reader 24 Platformy Technologiczne 2014 Wołanie Read dla każdego rekordu –Zwraca false gdy brak danych Dostęp do pól –Dostęp poprzez indeks lub nazwę –Funkcje Get… - najlepsza wydajność Zamknięcie DataReader Zamkniecie połączenia while (myReader.Read()) { str += myReader[1]; str += myReader["field"]; str += myReader.GetDateTime(2); } while (myReader.Read()) { str += myReader[1]; str += myReader["field"]; str += myReader.GetDateTime(2); } // Open Connection and create command SqlConnection conn = new SqlConnection("data source=localhost; initial catalog=pubs; integrated security=true"); SqlCommand cmdAuthors = new SqlCommand("select * from Authors", conn); conn.Open(); // Create DataReader and read data SqlDataReader dr; dr = cmdAuthors.ExecuteReader(); while (dr.Read()) { lstBuiltNames.Items.Add(dr["au_lname"] + ", " + dr["au_fname"]); } // Close DataReader and Connection dr.Close(); conn.Close();
Transakcje Platformy Technologiczne Transakcje lokalne Dostęp z jednego połączenia Udostępnione przez ADO.NET Transakcje rozproszone Wykonywane na wielu połączniacj Użycie Microsoft Distributed Transaction Component (MSDTC) namespace System.Transaction
Poziomy izolacji Platformy Technologiczne Definiują blokady na odczyt i zapis ADO.NET zapewnia różne poziomy izolacji ReadUncommittedDostęp do zablokowanych danych Dirty reads ReadCommittedOdczyt zablokowanych wierszy zabroniony Brak dirty read, może wystąpić phantom row Non-repeatable reads RepeatableReadReadCommitted bez non-repeatable reads SerializableDostęp w seriach Najwyższy poziom izolacji Nie występują phantom rows
Transakcje Platformy Technologiczne ADO.NET wspiera tranzakcyjność Transakcję rozpoczynamy poprzez metodę BeginTransaction która zwraca obiekt transakcji. Transakcja wspiera metody wykonujące zmiany na bazie danych – polecenia (Command) Transakcja jest: Zatwierdzana poprzez Commit Wycofywana poprzez Rollback
Transakcje Platformy Technologiczne Stworzenie obiektów IDbCommand cmd1 = con.CreateCommand(); cmd1.CommandText = "DELETE [OrderDetails] WHERE OrderId = 10258"; cmd1.Transaction = trans; cmd1.ExecuteNonQuery(); IDbCommand cmd2 = con.CreateCommand(); cmd2.CommandText = "DELETE Orders WHERE OrderId = 10258"; cmd2.Transaction = trans; cmd2.ExecuteNonQuery(); SqlConnection con = new SqlConnection(connStr); IDbTranaction trans = null; try { con.Open(); trans = con.BeginTransaction(IsolationLevel.ReadCommitted); 1. Definicja trans.Commit(); catch (Exception e) { if (trans != null) trans.Rollback(); } finally { try { con.Close(); } 3. Zatwierdzenie lub cofnięcie wyników
Tryb bezpołączeniowy – Data Set Platformy Technologiczne „Baza danych” utrzymywana w pamięci (struktura relacyjna) DataTable DataColumn DataRow DataRelation Tables DataTable Relations DataRelation DataRow(s) DataColumn Constraint(s) DataTable DataViewManager DataView
Data Set Platformy Technologiczne Gdy dane muszą być edytowane lub gdy do bazy trzeba dodawać i usuwać rekordy. Gdy zachodzi potrzeba organizowania danych - filtrowania, sortowania czy wyszukiwania Gdy rekordy pobrane z bazy danych będą przetwarzane w wielu iteracjach Gdy wynikowy zbiór danych pomiędzy kolejnymi odwołaniami do tej samej strony musi zostać zachowany w obiekcie Session lub Cache. Do przekazywania wyników działania obiektów warstwy biznesowej i usług Web Service odłączony obiekt DataSet może być serializowany do postaci XML i przesyłany z wykorzystaniem protokołu HTTP
Data Set vs. Data Reader Platformy Technologiczne DataSetDataReader Operacje odczytu i zapisuTylko do odczytu Wiele tabel z różnych źródełOparty o jedno polecenie SQL BezpołączeniowyPołączeniowy Źródło dla wielu kontrolekŹródło dla jednej kontrolki Przesuwanie się w przód i tyłPrzesuwanie tylko do przodu Wolniejszy dostępSzybszy dostęp Wspierany przez narzędzia automatyzujące pracę Wymaga ręcznej implementacji
Data Set - budowa DataSet składa się z Kolecji DataTable Kolekcji DataRelation DataTable składa się z DataTableColumns (= schema definition) DataTableRows (= data) DefaultView (DataTableView) DataRelation Łączy dwa obiekty DataTable definiujue ParentTable i ParentColumns oraz ChildTable i ChildColumns Dostęp do: DataTable DataSet.Tables[0] DataSet.Tables[“tablename”] DataColumn DataTable.Columns[0] DataTable.Columns[“columnna me”] DataRow DataTable.Rows[0] Pola tabeli DataRow[0] DataRow[“columnname”] 32 Platformy Technologiczne 2014
Typowany i nietypowany Data Set Typowany Data Set Informacje o typach dołączane są do obiektu Możliwy do stworzenia z poziomu VS / poprzez xsd Mniej podatny na błędy Rozwiązanie sztywne Odwołanie: MyDataSet.News[0].Title Nietypowany Data Set Nie posiada wbudowanego schematu Rozwiązanie bardziej elastyczne Odwołanie: MyDataSet.Tables[“News”].Rows[0][“Title”] 33 Platformy Technologiczne 2014
Zdarzenia w Data Table Platformy Technologiczne Dla kolumn: ColumnChanging, ColumnChanged DataColumnChangeEventsArgs: Column, ProposedValue, Row Dla wierszy: RowChanging, RowChanged, RowDeleting, RowDeleted DataRowChangeEventArgs: Action (Add, Change, ChangeCurrentAndOriginal, ChangeOriginal, Commit, Delete, Nothing, Rollback), Row Dla tabel: TableClearing, TableCleared, TableNewRow DataTableClearEventArgs: Table, TableName, TableNamespace DataTableNewRowEventArgs key member: Row
Data Adapter Platformy Technologiczne DataAdapter służy jako most pomiędzy DataSetem a źródłem danych pozwalający na wymianę danych. DataAdapter reprezentuje zestaw poleceń oraz połączenie bazodanowe które są uzywane do wypełnia DataSet oraz aktualizacji bazy. Dane są wymieniane poprzez zapytania SQL lub procedury składowane. Właściwości: SelectCommand – odczytuje dane ze źródła InsertCommand – zapisuje dane z DataSet do bazy UpdateCommand – aktualizuje dane w bazie danymi z DataSet DeleteCommand – usuwa dane z DataSet Metody: Fill – odświeża DataSet danymi z bazy (używa SELECT) Update – przenosi zmiany z DataSet do bazy (używa INSERT, UPDATE, DELETE)
Data Adapter - polecenia Platformy Technologiczne Tworzone na trzy sposoby Użycie obiektu CommandBuilder by stworzyć Command podczas wykonania Proste do realizacji, narzut na wykonanie Ograniczenie do Select dla jednej tabeli Poprzez Visual Studio w trakcie tworzenia aplikacji Proste do realizacji, brak narzutu na wykonanie Ograniczenie do Select dla jednej tabeli Stworzenie programowo podczas tworzenia aplikacji Wysoka kontrola i wydajność Brak ograniczeń Narzut na czas implementacji
Command builder Platformy Technologiczne Obiekt CommandBuilder generuje polecenia wymagane do aktualizacji źródła danych po wprowadzeniu zmian w obiekcie DataSet. Ograniczenia: polecenie Select dotyczy pojedynczej tabeli tabela w bazie musi mieć klucz główny lub unikatową kolumnę zawartą w oryginalnym poleceniu Select DataTable dt= ds.Tables["movies"]; // Use command builder to generate update commands SqlCommandBuilder sb = new SqlCommandBuilder(da); // Add movie to table DataRow drow = dt.NewRow(); drow["movie_Title"] = "Taxi Driver"; drow["movie_Year"] = "1976"; dt.Rows.Add(drow); // Delete row from table dt.Rows[4].Delete(); // Edit Column value dt.Rows[5]["movie_Year"] = "1944"; // Update underlying Sql Server table int updates = da.Update(ds, "movies"); MessageBox.Show("Rows Changed: " +updates.ToString());
Data Adapter - tworzenie Platformy Technologiczne Zapisanie zapytania w DataAdapter Konstruktor ustawia wartość SelectCommand Gdy wymagane, utworzenie InsertCommand, UpdateCommand, DeleteCommand SqlDataAdapter da = new SqlDataAdapter ("select * from Authors",conn); da.SelectCommand.CommandText; da.SelectCommand.Connection;
Data Set - tworzenie Platformy Technologiczne Ładowanie danych poprzez SelectCommand obiektu DataAdapter Definicja SQL, przez który zostaną załadowane dane SelectCommand jako konstruktor private void Demo() { SqlDataAdapter da = new SqlDataAdapter( "SELECT City FROM Authors", "Server=localhost; Database=Pubs; Integrated Security=SSPI" ); DataSet ds = new DataSet(); da.Fill( ds, "Authors" ); // Opens and closes a connection foreach ( DataRow dr in ds.Tables[ "Authors" ].Rows ) Console.WriteLine( dr[ "City" ] ); // Writes list of cities }
Data Set - tworzenie Platformy Technologiczne Tworzenie i załadowanie danymi DataTable Fill wywołuje SelectCommand obiektu DataAdapter Dostęp do DataTable DataSet ds = new DataSet(); da.Fill(ds, "Authors"); ds.Tables["Authors"].Rows.Count; string str=""; foreach(DataRow r in ds.Tables["Authors"].Rows) { str += r[2]; str += r["au_lname"]; }
Wypełnianie Data Set Platformy Technologiczne Wydajność Zdefiniowanie schematu przed wypełnieniem DataSet DataTables, DataColumns, DataRelations są znane przed załadowaniem danych Zwiększenie wydajności Tworzenie typowanych DataSet: dsCustomers.Customers.BeginLoadData(); daCustomers.Fill(dsCustomers.Customers); dsCustomers.Customers.EndLoadData(); dataGrid1.DataSource = dsCustomers.Customers.DefaultView; Dane z wielu DataAdapter DataSet może przechowywać dane z wielu obiektów DataAdapter 1 DataAdapter = 1 DataTable Wywołanie metody Fill Określenie tabeli daCustomers.Fill(dsCustomerOrders.Customers); daOrders.Fill(dsCustomerOrders.Orders); dataGrid1.DataSource = dsCustomerOrders.Customers.DefaultView;
Data Set - podsumowanie Platformy Technologiczne DataSet może: Przechowywać dane w wielu powiązanych tabelach Modelować zależności między tabelami Zarządza constrainami Daje dostęp do widoków celem bardziej efektywnego wyświetlania danych Być przesyłany pomiędzy procesami i warstwami DataSet i XML: XML może zostać załadowany do DataSet DataSet może zostać przesłany jako XML DataSet może wczytywać xsd
Data View Platformy Technologiczne DataView służy modyfikowaniu DataTable celem wyświetlenia potrzebych danych DefaultView zwraca standardowy widok dla DataTable Modyfikacja widoku z DataSet poprzez filtry DataView dv = ds.Tables["Authors"].DefaultView; DataView dv = new DataView(ds.Tables["Authors"]); dv.RowFilter = "state = 'CA'";
Relacje Platformy Technologiczne Kolumna rodzica Kolumna dziecka Stworzenie relacji Orders table Customers table DataSet parentCol childCol DataRelation DataColumn parentCol = ds.Tables["Customers " ].Columns["CustomerID " ] childCol = ds.Tables["Orders " ].Columns["CustomerID " ] dr = New DataRelation _ („CustOrders", parentCol, _ childCol) ds.DataRelations.Add(dr)
Nawigacja poprzez relacje Platformy Technologiczne ds.Tables[index].Rows[index].GetChildRows("relation"); ds.Tables[index].Rows[index].GetParentRow("relation"); Customers Orders GetChildRows GetParentRow DataSet DataView tableView; DataRowView currentRowView; tableView = new DataView(ds.Tables["Customers"]); currentRowView = tableView[dgCustomers.SelectedIndex]; dgChild.DataSource = currentRowView.CreateChildView("CustOrders"); Customers Orders CreateChildView DataRowView DataView DataSet
Modyfikacja danych Platformy Technologiczne BeginEdit rozpoczyna edycję danych EndEdit i CancelEdit kończą edycję danych DataRos drEmployee = dtEmployees.Rows(3) drEmployee.BeginEdit() drEmployee("FirstName") = "John" drEmployee("LastName") = "Smith" drEmployee.EndEdit() Wstawianie wiersza Stworzenie wiersza DataRow drNewEmployee = dtEmployees.NewRow() Wypełnienie danymi drNewEmployee("EmployeeID") = 11 drNewEmployee("LastName") = "Smith" Dodanie do DataTable dtEmployees.Rows.Add(drNewEmployee) Jednowierszowo dtEmployees.Rows.Add( New Object() {11, "Smith"})
Modyfikacja danych Platformy Technologiczne Usuwanie wiersza Metoda Remove Usuwa wiersz z kolekcji Przykład: dtEmployees.Rows.Remove(drEmployee) Metoda Delete klasy DataRow Oznacza wiersz jako usunięty Wiersz staje się „ukryty”, możemy uzyskać do niego dostęp Przykład: drEmployee.Delete()
Śledzenie zmian w Data Set Platformy Technologiczne DataRow może przechowywać wiele wersji wiersza: DataRowVersion.Current Aktualna wartość DataRowVersion.Original Wartość przed dokonaniem zmian DataRowVersion.Proposed Wartość w trakcie cyklu BeginEdit / EndEdit DataRowVersion.Default Wartość standardowa
Diagram stanów Data Row Platformy Technologiczne
Row versions Platformy Technologiczne CURRENTORIGINALPROPOSED WhiteWhiteN/A WhiteWhiteBrown BrownWhiteN/A dataRow.BeginEdit(); dataRow[ "au_lname" ] = "Brown"; dataRow.EndEdit(); dataRow[ "au_lname", DataRowVersion.Current ] // Brown dataRow[ "au_lname", DataRowVersion.Original ] // White
Modyfikacja źródła danych Platformy Technologiczne Modyfikacja źródła danych przez DataAdapter InsertCommand, UpdateCommand, DeleteCommand Modyfikacje są zapisywane poprzez metodę Update obiektu DataAdapter DataAdapter przeszukuje wiersze pod kątem RowState Wykonuje akcję zgodnie ze stanem wiersza RowState = Modified RowState = Unchanged RowState = Added RowState = Modified RowState = Deleted Use UPDATE command Ignore Use INSERT command Use UPDATE command Use DELETE command DataRows in DataTable
Optymalizacja zmian Platformy Technologiczne DataSet oraz DataTable wspierają metodę GetChanges Wywołanie bezargumentowe Pobiera wiersze, których RowState jest inny niż Unchanged Wykorzystanie podczas przekazywania między warstwami dsChanges = ds.GetChanges(); GetChanges z argumentem RowState Wiersze, które mają określony RowState Pozwala zarządzać kolejnością aktualizacji changes = ds.GetChanges( DataRowState.Added ); Medota Merge pozwala na scalenie danych
Spójność danych Platformy Technologiczne „A” czyta wiersz „B” zmienia FirstName z "Bob" na "Robert" i zapisuje zmiany „A” zmienia FirstName na "James”i próbuje aktualizować bazę Column nameOriginal valueCurrent valueValue in database CustID101 LastNameSmith FirstNameBob Column nameOriginal valueCurrent valueValue in database CustID101 LastNameSmith FirstNameBobRobertBob Column nameOriginal valueCurrent valueValue in database CustID101 LastNameSmith FirstNameBobJamesRobert
Obsługa współbieżnego dostępu Platformy Technologiczne Tryb bezpołączeniowy używa podejścia optymistycznego (optimistic concurrency) Zwalnianie blokad podczas rozłączania Możliwość konfliktów Dane mogły zostać zmienione Usunięcie wiersza Zmiana wartości w polu wiersza Wykrywanie konfliktów Data Adapter Configuration Wizard pozwala generować zapytania SQL wykrywające konflikty Podczas aktualizacji: Porównanie bieżących wartości z oryginalnymi (where …) Różnice powodują konflikt Dodanie do tabeli pola timestamp - aktualizacja pola przy zmianie wartości.
Rozwiązywanie konfliktów Platformy Technologiczne Właściwość HasErrors Sprawdza DataSet, DataTable, DataRow Jedna ze strategii: “Last in wins” – zmiany są zapisywane niezależnie od stanu Zatrzymanie wartości w DataSet i aktualizacja później Odrzut konfliktów i wypełnienie ich danymi z DataSet Odrzut konfliktów i wypełnienie ich danymi z bazy
SqlDataSource Platformy Technologiczne Atrybuty kontrolki SqlDataSource: ConnectionString – łańcuch połączenia. ProviderName – nazwa dostawcy danych. SelectCommand – polecenie SQL zawierające treść zapytania do bazy danych lub nazwa procedury składowanej do wykonania. <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|\CDDB.mdf; Integrated Security=True; User Instance=True" ProviderName="System.Data.SqlClient" SelectCommand="SELECT * FROM [Kategorie]">
SqlDataSource Platformy Technologiczne Kofiguracja poleceń bazodanowych <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString=" " SelectCommand="SELECT * FROM [Kategorie]" DeleteCommand="DELETE FROM [Kategorie] WHERE [KatID] InsertCommand="INSERT INTO [Kategorie] ([Nazwa]) VALUES UpdateCommand="UPDATE [Kategorie] SET [Nazwa] WHERE [KatID]