Efektywne wykorzystanie danych w .NET

Slides:



Advertisements
Podobne prezentacje
Copyright © The OWASP Foundation Permission is granted to copy, distribute and/or modify this document under the terms of the OWASP License. The OWASP.
Advertisements

Indeksy w bazie danych Oracle
Procedury wyzwalane Procedura wyzwalana (ang. trigger) - stanowi kod użytkownika przechowywany wewnątrz bazy i uruchamiany w określonych sytuacjach np.
Projektowanie bazy danych
Decyzje projektowe w .NET Framework
SQL INJECTION Wykorzystanie błędów w językach skryptowych
Bazy danych II Instrukcja SELECT Piotr Górczyński 25/08/2001.
18/11/ Języki programowania 1 Piotr Górczyński Biblioteki.
ADO.NET Konflikty i kłopoty
Komponenty bazy danych Baza danych Jest to uporządkowany zbiór powiązanych ze sobą danych charakterystycznych dla pewnej klasy obiektów lub zdarzeń,
WPROWADZENIE DO BAZ DANYCH
MS Access 2003 Kwerendy Paweł Górczyński.
MS Access 2000 Kwerendy Piotr Górczyński 25/08/2001.
25/08/ Bazy danych II Piotr Górczyński Instrukcja UPDATE.
25/08/ Bazy danych II Piotr Górczyński MS Access – Action Query.
25/08/ Bazy danych II Piotr Górczyński Administracja MS SQL.
20/09/ Języki programowania 1 Piotr Górczyński Kreator form.
18/11/ Języki programowania 1 Piotr Górczyński Łączenie z bazą danych.
Wycofywanie potwierdzonych transakcji
Tworzenie ASP.NET Web Form
Arkadiusz Twardoń ZTiPSK
Aplikacje ASP.NET Arkadiusz Twardoń ZTiPSK
Opracowanie studium przypadku w SAS ETL Studio
Co to jest studium przypadku?
Bezpieczeństwo Procedury składowane Funkcje i Wyzwalacze
Marta Kupiec Adrian Macal
WYZWALACZE (TRIGGERY) Wyzwalacz jest specjalnym rodzajem procedury składowanej, która może być wykonana w odpowiedzi na jedną z trzech sytuacji: UPDATE.
Programowanie wizualne PW – LAB5 Wojciech Pieprzyca.
Warstwa dostępu do danych
Information Bridge Framework platforma integracji Microsoft Office 2003 z aplikacjami Line of Business Krzysztof Michalski10/01/2005.
Rozproszone bazy danych
WYKONYWANIE ZAPYTAŃ Przygotował Lech Banachowski na podstawie: 1.Raghu Ramakrishnan, Johannes Gehrke, Database Management Systems, McGrawHill, 2000 (książka.
Technologia.Net Bazy danych. Technologia ADO.Net Służy do dostarczania danych z rożnych źródeł (baz danych) do aplikacji Jest produktem Microsoft Umożliwia.
Technologia ASP.NET.
Język SQL (Structured Query Language) DDL (Data Definition Language)
Bezpieczeństwo baz danych
Przykład włamania do aplikacji internetowej poprzez modyfikację zapytań SQL Skrypty ASP Serwer bazy danych MS SQL Server Piotr Kuźniacki BDi.
MySQL – ODBC - ACCESS.
Wirtualna baza SQL zgodna z SQL Server SQL as a Service
Administracja serwerem bazy danych Oracle 11g Zarządzanie strukturą bazy danych Wykład nr 2 Michał Szkopiński.
ANNA BANIEWSKA SYLWIA FILUŚ
Prezentacja i szkolenie
ASP BAZY. 2.2 S. Wolek Wst. do Inf. Połączenie z bazą danych przez ADO (ActiveX Data Object) do: - źródła ODBC - bazy z podanie nazwy sterownika ODBC.
Platformy Technologiczne ADO.NET
SQL - Structured Query Language
Aplikacje bazodanowe ADO.NET PHP i MySQL
Tworzenie Aplikacji Internetowych dr Wojciech M. Gańcza 3.
Komendy SQL do pracy z tabelami i bazami
18/11/ Języki programowania 1 Piotr Górczyński Kontrolki.
ADO .NET.
Serwery Aplikacji Tworzenie bezpiecznych aplikacji.
Projektowanie stron WWW
PLATFORMY TECHNOLOGICZNE ADO.NET mgr inż. Tomasz Gawron.
1 SBD, L.Banachowski Zaawansowane cechy SQL Powtórzenie wyk ł adu 5.
Autor: Damian Urbańczyk
Technologia.Net Bazy danych. Technologia ADO.Net Służy do dostarczania danych z rożnych źródeł (baz danych) do aplikacji Jest produktem Microsoft Umożliwia.
1. Logowanie z usługą Active Directory. a) logowanie do domeny Windows 2003 Server odbywa się znacznie szybciej niż w poprzednich wersjach. b) nie ma odwołania.
Komendy SQL do pracy z danymi
XML w bazach danych.
.NET i Bazy Danych Projekt: Wadim Grasza.
Optymalna konfiguracja Microsoft SQL Server 2014
Projektowanie postaci formularza:
Wykład 3 Prowadzący: dr Paweł Drozda. Użytkownik bazy danych – osoba lub aplikacja, mająca dostęp do części danych zgromadzonych w bazie Uprawnienia –
ASP.NET Kontrolki źródła danych i prezentacji danych w ASP.Net
ASP.NET Dostęp do bazy danych z poziomu kodu Elżbieta Mrówka-Matejewska.
Temat: Tworzenie bazy danych
Strukturalny język zapytań SQL - historia
Aplikacje i usługi internetowe
Technologie Informacyjne Bazy danych
Zapis prezentacji:

Efektywne wykorzystanie danych w .NET Tomasz Kopacz Praktyczne bazy 90 min Efektywne wykorzystanie danych w .NET

O czym będzie Część I Część II Jak pisać przy użyciu .NET, SQL-a i MSDE Podstawowe obiekty DataSet DataBinding Część II Jak wykorzystać MSDE we własnej aplikacji Część I Jak pisać przy użyciu .NET, SQL-a i MSDE Część II Jak administrować MSDE Dokładniej – kilka uwag jak napisać moduł który zapewni użytkownikom naszego programu mechanizmy do podstawowej administracji MSDE

Kilka słów o połączeniu IConnection Pula Mapuje po dokładnej postaci ConnectionString Dodatkowe parametry: Connection Lifetime; Max Pool Size / Min Pool Size; Pooling=‘false’ POŁĄCZ, ZRÓB CO TRZEBA I ODŁĄCZ JAK NAJSZYBCIEJ Na raz jedno polecenie przy użyciu jednego IConnetion Pierwszą czynnośćią jaką trzeba wykonać chcąc pracować z danymi w ADO.NET jest fizyczne połączenie się z bazą. W ADO.NET za tą operację odpowiada IConnection implementowany przez danego providera. W przypadku SQL Server jest to provider SqlClient, napisany w całości w kodzie zarządzalnym w .NET. Inny to np. provider dla sterowników OleDB czy ODBC W .NET funkcjonuje pula połączeń Zamykanie połączenia != fizyczne usunięcie Nie ma różnicy pomiędzy Close() a Dispose() Mapuje po dokładnej postaci ConnectionString Spacje, inny użytkownik… -> nowa pula Pula dla: AppDomain (równoległe serwisy ASP.NET na WWW itp.) , nowego użytkownika (logowanie zintegrowane) Dodatkowe parametry: Connection Lifetime – gdy połączenie wraca do puli, to to jest czas życia, zanim połączenie nie zostanie usunięte. Używane w klastrach, do wyrównania obciążeń Max Pool Size / Min Pool Size; Pooling=‘false’ Zdarzenie InfoMessage/StateChanged– zależą od tego do czego provider je wykorzysta POŁĄCZ, ZRÓB CO TRZEBA I ODŁĄCZ JAK NAJSZYBCIEJ; Bez „trzymania” połączeń na zaś; Wyjątek – niektóre aplikacje „desktop” typu client-server Na raz jedno polecenie przy użyciu jednego IConnetion Jedno polecenie - kursor do „przeglądania” zestawu rekordów Drugie - wykonywania SP aktualizującego dane…

Połączenie i hasło Naturalne miejsce Hasło czystym tekstem??? SqlConnection db = new SqlConnection(„ Data Source=localhost; Integrated Security=SSPI; Initial Catalog=Northwind"); … password=jan;user id=jan”); … db.Open(); Naturalne miejsce WebForms -> web.config WinForms -> plikExe.config Hasło czystym tekstem??? Zakodować Rijandel System.Convert.ToBase64String DPAPI – zajrzeć na www.gotdotnet.com Pytanie w jaki sposób zapisać hasło (a w ogóle – jak zapisać cały łańcuch połączenia). Hasło - oczywiście – najprościej używać logowania zintegrowanego – nie zawsze się da…. Naturalne miejsce WebForms -> web.config; WinForms -> plikExe.config W projekcie – App.Config (IDE kopiuje i zmienia nazwę) Uwaga! .config parsowany raz Ignoruje zmiany w trakcie działania programu Hasło czystym tekstem??? WebFroms -> web.config niedostępny z zewnątrz Administrator WWW??? WinForms -> plikExe.config + notepad… Może tryb zintegrowany Jak nie – DAPI, Rijandel, cokolwiek nie ma pewnego zabezpieczenia, hasło i tak jest w programie RIjhandel, DES, jakiś inny algorytm DPAPI – zaszyfrowany tekst do odczytania tylko na tym samym komputerze Ten sam mechanizm jak szyfrowanie plików EFS Logowanie zintegrowane W dalszych przykładach „hasło czystym tekstem”, nawet na stałe zakodowane w programie. Tak nie należy robić!

Główne obiekty użytkowe IDataCommand IDataReader Jednokierunkowy kursor tylko do odczytu Generowany przez IDataCommand DataSet Baza danych po stronie aplikacji klienckiej Wypełniany przez IDataAdapter Polecenia IDataCommand W „środku” wykorzystuje IDataReader XML Synchronizacja Transakcje Po uzyskaniu połączenia, można już zaczxąć wykonywać określone operacje na źródle danych. IDataCommand Wykonanie polecenia, parametry itp IDataReader Jednokierunkowy kursor tylko do odczytu Generowany przez IDataCommand DataSet De facto baza danych po stronie aplikacji klienckiej Filtry, wyszukiwanie, dodatkowe wyrażenia Wypełniany przez IDataAdapter Polecenia IDataCommand W „środku” wykorzystuje IDataReader XML Synchronizacja (uaktualnianie danych). Dotyczy różnych DataSet, źródła danych itp Transakcje: SQLTransaction/OleDbTransaction – pobiera się z połączenia a potem dodaje do konkretnej operacji (polecenia IDataCommand; w SQL-u można tworzyć SavePoints (punkty zapisu)

DataSet a DataReader Nie można powiedzieć jednoznacznie „który lepszy” IDataReader Szybki odczyt ale „jednokierunkowy” Brak mechanizmów aktualizacji Też „databinding” irr(”MojePole”)… DataSet Gdy potrzebna tymczasowa kopia (cache) XML z przyległościami Model bezpołączeniowy Często stawiane pytanie jest – czy lepszy DataSet Czy DataReader Nie można powiedzieć jednoznacznie „który lepszy” IDataReader Szybki odczyt ale „jednokierunkowy” Brak mechanizmów aktualizacji Też „databinding” Na przykład - do listy wyboru Trudno utrzymać separację kodu od bazy Aż się prosi jakieś irr(”MojePole”)… DataSet Gdy potrzebna tymczasowa kopia (cache) Większość kontrolek-pojemników w .NET samo nie przechowuje danych a bazuje m. innymi na DataSet XML i okolice Model bezpołączeniowy W zasadzie klienta nie interesuje typ bazy Wypełnianiem zajmują się specjalistyczne obiekty

Obsługa dużych obiektów (BLOB) Nie chcemy na raz całego obiektu Jeżeli tylko do odczytu IDataReader SequentialAccess + GetBytes() Fragmenty: Wsparcie ze strony MS SQL TEXTPTR –varbinary(16) READTEXT tabela.kolumna ptr przesunięcie wielkość Pierwszy przykład, gdzie na pewno warto stosować IDataReader Nie więcej niż 2 minuty! To jest jedno z miejsc, gdzie warto stosować datareader Nie chcemy na raz całego obiektu – bo jeżeli jednak chcem Jeżeli tylko do odczytu IDataReader SequentialAccess (specjalny trybo otwarcia idatareader) + GetBytes() Uwaga! Z bazy „idzie” cały strumień, tylko klient odczytuje go po kawałku Jeżeli aktualizacje, albo chcemy pobierać fragmenty Wsparcie ze strony MS SQL TEXTPTR – tak naprawdę varbinary(16); można go ściągnąć do aplikacji klienckiej. READTEXT tabela.kolumna ptr przesunięcie wielkość Jakoś opakować?

IDataReader? IDataReader Mały koszmarek: Scenariusz: strona aspx z dynamicznie generowaną tabelą na podstawie IDataReader Każde odświeżenie strony to zapytanie do bazy Mały koszmarek: if (!irr.IsDBNull(irr.GetOrdinal(„Pole”))… Przykład, gdzie wykorzystanie IDataReader jest co najmniej dyskusyjne Gotowe

DataSet i Cache „Globalny DataSet” ASP.NET / obiekty biznesowe Drzewo kategorii, menu, coś „półstatycznego” DataSet GetMenu() { DataSet menu=Cache("MenuDS"); if(menu==null) { SqlDataAdapter da; //I zainicjować itp… menu=new DataSet(); da.Fill(menu); Cache("MenuDS") = menu; } return menu; } Jak podobną funkcjonalność można zrealizować przy użyciu DataSet Klasyczny przykład wykorzystania DataSet W takich systuacjach warto DataSet Można czas przez jaki cache jest prawidłowe Można też definiować czas przechowywania w cache Callback po to by być poinformowanym o usunięciu czegoś z cache Głównie ASP.NET, ale też obiekty biznesowe Drzewo kategorii, menu, coś „półstatycznego” Dodać do pamięci podręcznej Synchronizować tylko zapisy Ale zwykle są to obiekty tylko do odczytu

DataSet, DataAdapter i ADO.NET Baza danych 1 Klient tworzy żądanie wyświetlenia strony 2 Tworzenie obiektów SqlConnection i SqlDataAdapter SqlConnection Wypełnienie DataSet z DataAdapter i zamknięcie połączenia 3 SqlDataAdapter Zwraca DataSet do klienta 4 Zmiana informacji przez użytkownika 5 Provider 6 Aktualizacja danych DataSet Wykorzystanie SqlDataAdapter do otwarcia SqlConnection, aktualizacja danych w bazie i zamknięcie połączenia 7 Teraz chciałbym pokazać, w jaki sposób funkcjonuje zwykła aplikacja bazodanowa w .NET Po wstępie, chciałbym pokazać jakie są relacje przy DataSet Kontrolka DataGrid Klient

DataSet Odwzorowanie bazy danych, ale… Rada: Podzbiory elementów Synchronizacja zmian Rada: Baza i niezależny DataSet jako obiekt pomocniczy - biznesowy Czym tak naprawdę jest dataset? Do czego możemy go użyć Dataset – może odwzorować bazę Składa się z szeregu kolekcji DataColumn jest cechą DataTable a równocześnie determinuje strukturę DataRow Odwzorowanie bazy danych, ale… Jak wybrać podzbiór elementów Co z synchronizacją zmian w schemacie Rada - może Baza i niezależny DataSet jako obiekt pomocniczy - biznesowy

DataSet – projektant lub kod Customer, Invoice, InvoiceItem, Product Uwaga! Projektujemy więzy i relacje! UniqueConstraint ForeginKeyConstraint DeleteRule,UpdateRule (AcceptRejectRule) Mocna kontrola typów Jak projektować. Można pisać kolekcje, dodawać elementy itp Warto pamiętać, że jeżeli mamy dataset z mocną kontrolą typów, to zawsze możemy sięgnąć do wersji „bez kontroli” – jak będzie wygodniej Przykład: Customer, Invoice, InvoiceItem, Product Zupełnie w oderwaniu od bazy Uwaga! Projektujemy więzy i relacje – czy na pewno relacja będzie wykorzystana? UniqueConstraint – wartość unikalna w kolumnie Zwykle jest to klucz główny ForeginKeyConstraint DeleteRule, UpdateRule None, Cascade SetDefault, SetNull AcceptRejectRule – acceptchanges/rejectchanges ForeginKeyConstraint != indeks Mocna kontrola typów – czasami problemy GetType() można odczytać typ danego pola Pamiętać o cecha systemów typów w .NET Convert.ChangeType… zmienić element na odczytane pole VB.NET bez włączonej mocnej kontroli typów – może być wygodniejszy Warto pamiętać że w .NET Convert.ChangeType pozwala zmienić typ obiektu obj na taki jaki wskazuje np. typ pola

Relacje Ustawiać tylko te co są potrzebne do nawigacji Relacja rodzic – potomek DataRelation rel=ds.Relations.Add( "TestRel", ds.Invoice.Columns["id"], ds.InvoiceItem.Columns["id_inv"]) W ramach DataSet możemy definiować związki pomiędzy elementami w DataTable Definiując relacje można wybierać powiązane rekordy wg. zasady rodzic/potomek Jak za dużo – zwalnia True – tworzy także więzy Więzy muszą być spełnione DataColumn[] aParent= { ds.Tables[0].Columns[0], ds.Tables[0].Columns[1] } DataColumn[] aChild= { …} ds.Relations.Add("TestRel",aParent,aChild,true)

Relacje - poruszanie się GetParentRow/GetChildRows ((MainDS.Invoice)ds.InvoiceItem[0].GetParentRow(rel)) .inv_date… ds.Invoice[0].GetChildRows(rel).Length… Jeżeli już mamy relacje, to możemy się poruszać po dataset zgodnie z ustalonymi zasadami. Wyrażenia (wartości kolumn itp.) DataView GetParent/GetChild Brak automatycznego wsparcia dla mocnej kontroli typów Trzeba rzutować

Triggery RowChanging, RowChanged ColumnChanging, ColumnChanged RowDeleting, RowDeleted Stan DataRowAction Add, Change, Commit, Delete, Rollback Nothing Czasami chcemy wiedzieć, kiedy nasz DataSet ulega zmianie (np. – w wyniku jakiejś akcji w naszym własnym programie). RowChanging – nie można zmieniać wartości; wyjątek! RowChanged może się pojawić 2 razy – raz po zmianie, 2 raz po AcceptChanges Add/Commit

Pola wyliczeniowe Generalnie szybkie Małe kłopoty z DataAdapter Można dodać do DataSet po wypełnieniu Język – patrz MSDN - temat DataColumn.Expression Property DataSet używany też do prezentacji czy przekształceń w warstwie logiki biznesowej. Warto móc dodać element wyliczeniow DataAdapter próbuje aktualizować pola wyliczeniowe – gener Generalnie szybkie Szybsze niż analogiczny kod w .NET który wypełni ręcznie dodatkowe pole Małe kłopoty z DataAdapter Raczej: z CommandBuilder Można dodać do DataSet po wypełnieniu Język – patrz MSDN - DataColumn.Expression Property DataColumn col=new DataColumn("TotalPrice"); col.DataType=typeof(decimal); col.Expression="cnt * value"; ds.InvoiceItem.Columns.Add(col); …ds.InvoiceItem[0]["TotalPrice"]

Ładowanie danych Ładowanie danych BeginLoadData DataTable.LoadDataRow(tablica,true) EndLoadData – włącza, wczytane sprawdza! EnforceConstraints Kolejny problem związany z DataSet – jak go szybko załadować. Do czego wykorzystać -zamiast je od razu ładować do bazy LoadDataRow – bierze tablicę i znajduje pasujące wartości w PK. Nawet jak nie ma włączonych więzów. (wartości null są zastępowane domyślną lub czymś wynikającym z AutoIncrement). Parametr true, to nowe dane są dodawane a na końcu umieszczane Begin/EndLoadData Turns off/on notifications, index maintenance, and constraints after loading data EnforceConstraints – np. by wczytać w dowolnej kolejnosci (podobnie jak zrzucanie więzów w SQL-u) Mnie się wydaje że słaba jednak jest czasami wygodniejsza. Kontrola typów nakładka na dataset – i tak analizowane są kolekcje itp

DataSet i XML XMLDataDocument Różne sposoby generowania DataSet Relacja.Nested=True ColumnMapping=MappingType.Attribute Transmisja DiffGram Szybko podejrzeć zawartość DataSet: myDS.WriteXml( Console.Out ) Lub: Process.Start("iexplore.exe",@"C:\TMP\tmp.xml"); Po co XML? Bo wygodny XMLDataDocument – inny widok danych z DataSet Xpath, wyszukiwanie, można Transformacja xslt i wyświetlenie, pobieranie wiersza dla danego XmlNode Nie można zmieniać atrybutów określających sposób generowania XML, gdy ten XML jest wygenerowany (np. – nested) Diffgram – bazuje na wersjach dataset i pozwala wygenerować dokument XML zawierajacy elementy oryginalne i zmienione. Wykorzystywany do serializacji, ale może też być wysłany do SQL 2000 z rozszerzeniami XML Domyślnie mapuje na elementy – ale można to przestawić na atrybuty Zasady łączenia schematów Transmisja DiffGram Różne sposoby generowania DataSet Struktura hierarchiczna Relacja.Nested=True Aby używać atrybuty zamiast elementów ColumnMapping=MappingType.Attribute Na marginesie – szybko podejrzeć zawartość DataSet: myDS.WriteXml( Console.Out ) Lub: Process.Start("iexplore.exe",@"C:\TMP\tmp.xml"); (WriteXML)

Demo Tworzenie DataSet Podstawowe operacje Klucze, triggery i relacje Dodanie pola Podstawowe operacje Klucze, triggery i relacje Ręczne tworzenie – w każdym miejscu w MSDN

Wyszukiwanie/filtrowanie DataTable.Select(…); DataTable.Find(rPK) Kilka różnych DataView na jednym DataSet (jednej kopii danych) Filtry: Zdarzenie ListChanged dt.DefaultView.RowFilter = ”Pole=‘Wartość’” dt.DefaultView.RowFilter = ”InvData=#mm/dd/yyyy#” dt.DefaultView.RowFilter = ”Parent.InvData=#mm/dd/yyyy#” Mamy już wypełniony DataSet, warto teraz zastanowicd się jak znalexc jakiś element… Znaleźć jakąś kolekcję wierszy (select) lub wartość wg PK DataTable.Select(…) Kilka różnych DataView na jednym DataSet (jednej kopii danych). Też aktualizacj Filtry: waga! Format daty/czasu zależy od ustawień (DateTimeFormatInfo ) Sortowanie Zdarzenie ListChanged ListChanged – jak się bazowy element zmienił i dataview się uaktualnia

DataView i wyszukiwanie Jeżeli szukamy nie wg PK, lepiej DataView Warto posortować wg. często filtrowanych pól DataView buduje wtedy INDEX Lepiej: v.Sort="Name”; v.FindRows(” KOPACZ”); Tworzenie DataView: DataView v = new DataView( customerTable, "City='Warszawa'", "Name, Surname DESC", DataViewRowState.OriginalRows ); v.FindRows(new object [] {„pole1”,”pole2”}); Przyspieszyć – wyszukiwanie po PK działa ładnie, ale… Inaczej – załóż Sort – buduje index Filtruje się TABELĘ

DataView i relacje DataView „budowany” na tabeli nadrzędnej Operatory Parent(NazwaRelacji).Pole Child(NazwaRelacji).Pole Avg,Sum,Max, itp Pozostał 3 przypadek, gdy mamy relacje? I chcemy szukać uwzględniając relacje DataView „budowany” na tabeli nadrzędnej Operatory Parent(NazwaRelacji).Pole Child(NazwaRelacji).Pole Avg,Sum,Max, itp DataRelation rel = ds.Relations.Add("TestRel",…); DataView view = new DataView(ds.Invoice, "Sum(Child(TestRel).value)>=600", "", DataViewRowState.CurrentRows);

Demo - wyszukiwanie Stworzenie DataView Bazowanie na tabelach Zabawy z wyrażeniami Bez XML CreateChildView – zwraca „potomny” widok połączony relacją OK

DataSet a „reszta świata” Czyli DataSet i baza danych

Podstawa to DataAdapter DataAdapter <-> baza SelectCommand CommandBuilder InsertCommand, UpdateCommand, DeleteCommand, DataAdapter <-> DataSet MissingSchemaAction/MissingMappingAction TableMappings.Add (tabela_bd,tabela_ds) ColumnMappings.Add (bd,ds) Jeden DataAdapter do aktualizacji jednej tabeli DataAdapter decyduje ile danych znajdzie się w DataSet DataSet został wypełniony, zdefiniowany – teraz trzeba go zsynchronizować z bazą danych. Odpowiada za to DataAdapter – w jego obrębie zdefiniowane są struktury określające mapowanie pomiędzy tym co zwraca IDataCommand, a DataSet MissingSchemaAction Co się dzieje gdy dane są dodawane do dataset a bazowej tabeli lub kolumny nie ma Add / AddWithKey dodaje kolumnę oraz odpowiedni klucz główny Error Ignore – nie dodaje MissingMappingAction co się dzieje gdy brakuje mapowania pomiędyz źródłem a bazą Error Ignore (pomija) Passthrough (tworzy nowy element) DataAdapter <-> DataSet Właściwości IDataAdapter TableMappings.Add (tabela_bd,tabela_ds) ColumnMappings.Add (bd,ds) DataAdapter <-> baza InsertCommand, UpdateCommand, DeleteCommand, SelectCommand „Normalne” polecenia ADO.NET CommandBuilder – pomocnik; nie wykorzystywać do dynamicznej budowy – chwilę trwa Uwaga! Zdrowo: jeden DataAdapter do aktualizacji jednej tabeli A potem w kodzie wywołać sekwencję kilku kolejnych Update Przy odczycie dataadapter może wypełnić kilka tabel DataAdapter decyduje ile danych znajdzie się w DataSet Stronicowanie RĘCZNIE przy wypełnianiu Data, zakres liczb, nawet wstępne filtrowanie

Szybko wygenerować DataSet DataAdapter może wygenerować DataSet Nazwy kolumn prawidłowe Tabele – Table,Table1… da.Update(ds,”Table1”) ds.WriteXmlSchema(…) XSD.EXE SqlCommand sql=new SqlCommand("select * from Customer; select * from Invoice",sqlConnection1); SqlDataAdapter da=new SqlDataAdapter(sql); DataSet ds=new DataSet(); …Mapowania da.FillSchema(ds); da.Fill(ds) A po co definiować dataset – niech się sam zrobi… Zmienić nazwę – lub mapowanie DataAdapter da bazuje na select * from Customers Można zapisać schemat i uruchomić xsd z linii poleceń

Jak (nie) budować dynamicznego kodu i filtrować SP z odpowiednimi parametrami (NULL – nie filtruj) Dynamiczna budowa UŻYWAĆ StringBuilder Sprawdzać parametry (SQL Injection) „where = ?” ALTER PROCEDURE GetCustomers ( @City NVARCHAR(15) … ) AS select * from Customers where (City=@City or @City is null) AND … select * from Customers where City=COALESCE(@City, City) AND … Kolejny problem – dataadapter decyduje ile elementów jest w bazie. Nie ma sensu kilku GB bazy przenosić na stację kliencką. Trzeba filtrować… Jak – albo odpowiednią procedurą przechowywaną, albo – dynamicznie sklejając polecenie SQL. Generalnie SP szybsze, ale nie zawsze – czasami jest zbyt skomplikowane (za dużo parametrów). Narzut na przekazywane parametry Dużo parametrów – narzut… Czasami budowa dynamiczna wygodniejsza Jeżeli już budować dynamicznie to: UŻYWAĆ StringBuilder – znacznie szybszy String jest obiektem STATYCZNYM; aby dopisać jeden znak kopiowany jest cały obiekt Sprawdzać parametry (SQL Injection) Budować parametryzowaną SQLCommand

Stronicowanie… Znaleźć coś co „wyznacza” strony Specjalne wyrażenie SELECT… SELECT TOP <LiczbaWierszyNaStronie> InvoiceID,Client,City … FROM Invoices WHERE InvoiceID NOT IN (SELECT TOP <LiczbaWierszyDoPominięcia> InvoiceID FROM Invoices ORDER BY Client, City) ORDER BY Client, City Kolejny problem – czasami mimo filtrów nadal danych za dużo – wtedy trzeba jakoś je „stronicować” Chodzi o pobranie fragmentu danych Uwaga na marginesie – programiści ASP.NET, grid – stronicowanie, ale i tak z bazy idzie „pełny” zestaw Znaleźć coś co „wyznacza” strony Zakres dat dokumentów,region,klient,grupa towarowa… Specjalne wyrażenie SELECT Trochę to kosztuje Lepiej – filtry itp. Ale czasami trzeba: Wybieramy ileś wierszy, ale takich, których id nie występują w zbiorze poprzednio wybranych elementów. Zjada zasoby serwera – ale czasami po prostu nie ma wyjścia.

Aktualizacja IDataAdapter Bazuje na wersjach wiersza Generowanie Dodane -> InsertCommand Zmienione -> UpdateCommand Usunięte -> DeleteCommand Generowanie Przy użyciu CommandBuilder Wystarczająco proste SelectCommand… Ręcznie Mamy już odczytane dane, wypełniony dataset, uległy zmianie elemnty i trzeba je przesłać z powrotem do bazy Jak je wygenerować? Tylko wspomnienie – co robimy i wstęp do kolejnego slajdu IDataAdapter Bazuje na wersjach wiersza Dodane -> InsertCommand Zmienione -> UpdateCommand Usunięte -> DeleteCommand Generowanie Przy użyciu CommandBuilder Bazuje na SelectCommand Ograniczenia ; gdy złożone SelectCommand. Ale – można inny da do wyboru danych, a inny do aktualizacji. Ręcznie Ważna kolejność aktualizacji – baza i tak sprawdzi spójność da.Update(ds,”Customer”); … da1.Update(ds.GetChanges(DataRowState.Deleted));

Problem – konflikt aktualizacji 3 wersje DataRowVersion Original, Current, Proposed, Default Wszystko zależy od …Command Porównanie wszystkich wartości Timestamp Wcale? 5 wersji DataRowState Added,Deleted,Modified,Unchanged Detached No ale mamy model bezpołączeniowy – ktoś mógł w międzyczasie zmienić bazę Detached Wiersz utworzony, ale nie jest elementem żadnej kolekcji Nie ma możliwości by zablokować wiersz przed edycją przez innych Wszystko zależy od …Command Decyzja czy można: Wszystkie pola Timestamp (ekonomiczne i rozsądne) Wcale (tzw. „ostatni ma rację”) Skąd w ogole dataadapter wie które elementy się „zmieniły” Jak się to dzieje? Każdy wiersz ma swój stan, a każda wartość swoją „wersję” 5 wersji DataRowState Added,Deleted,Modified,Unchanged Detached 3 wersje DataRowVersion Original, Current, Proposed, Default To samo wykorzystywane jest przy porównaniach – np.. Dla timestamp brana jest wartość „oryginalna”

Stany kolumn w DataSet Aby to zrozumieć, warto się przyjżeć temu diagramowi NIE ROZGADAĆ SIĘ!

Demo - Mapowanie + aktualizacje DataSet wypełniany z SP Kilka wyników z SP i generowanie automatyczne DataSet Konflikt 2 minuty

Czyli związywanie „czegoś” z „czymś” Databinding Czyli związywanie „czegoś” z „czymś”

DataBinding Głównie zastosowanie w prezentacji danych Pola związane relacjami Praktycznie - dowolna właściwość R/W do dowolnej właściwości Mamy dane, wiemy jak wymieniać je z bazą – teraz trzeba je jak najprościej pokazać. Ogólne uwagi Głównie zastosowanie w prezentacji danych CurrencyManager Tylko WinForms Web Form – trochę bardziej złożone Można też związywać z polami połączonymi relacją Związywanie pomiędzy wartościami kontrolek. Praktycznie - dowolna właściwość do dowolnej właściwości. Przykłady: Właściwość Panel.Visible do chkBox.Checked Pole z bazy steruje kolorem ramki Naprawdę dowolna właściwość którą można zapisać…

Składnia – Windows Forms „Proste związywanie” „Złożone związywanie” (complex binding) Związywanie z listą wartości (np. ListBox) wyboru DataSource/DisplayMember/ValueMember SelectedValue CurrencyManager dla danego DataSource NazwaKontrolki.DataBindings. Add(„Właściwość”,źródło,”element”) Jak wygląda składnia związywania w przypadku „bogatego” klienta, winforms. Proste związywanie – właściwości jako string Proste związywanie Jedna wartość „Złożone związywanie” (complex binding) Nie jest skomplikowane  Związywanie z listą wartości (np. ListBox) wyboru DataSource DisplayMembet – to co widać ValueMember – to co jest zwracane jako „wartość” DataSource ma implementować IList (DataTable, kolekcja, tablica…) IBindingList : IList, ICollection, IEnumerable Siatka (DataGrid) – specjalny przypadek, kolekcja elementów do związania Form1.BindingContext[MójDataset].Position -=1

Składnia – ASP.NET Podstawowa różnica Proste Złożone IDataReader Związywanie z kopią! (stąd -> kontrolka.DataBind()) Proste Złożone DataSource, DataTextField, DataTextFormatString, DataValueField IDataReader <asp:TextBox id=„TextBox1” text=‘<%# tbl.Rows[0][„Kolumna”] %> SqlCommand cmd=sqlconnection1.CreateCommand(); cmd.CommandText=„select id,name from Customer”; SqlDataReader rdr=cmd.ExecuteReader(); lstBox.DataSource = rdr; lstBox.DataTextField = „name”; lstBox.DataValueField = „id”; lstBox.DataBind(); Trochę inaczej jest w ASP.NET DataBind – fizyczne wypełnianie tego co wysyłane do klienta Podstawowa różnica Win Forms – binding do danych Web Forms – binding do kopii danych Stąd -> kontrolka.DataBind() (kopiowanie danych) Proste Złożone DataSource, DataTextField, DataTextFormat String, DataValueField DataBinding i tak jest „tylko do odczytu” W specjalny sposób ze stanu trzeba odczytać co się zmieniło Związywanie z DataReader: Stosować gdy dane często się zmieniają Też można w WinForms, ale częściej się spotyka w ASP.NET

Demo – binding i okolice Manipulacja wersjami pól Jak się zmieniają AcceptChanges Formatka master-detail Update wielopoziomowy w transakcji Przyciski poprzedni/następny DataBinding pomiędzy CheckBox a Enabled Panel-u 5 minut!!!! Mała uwaga – trzeba pilnować kiedy kontrolka zapisuje zmiany do źródła – generalnie przy stracie fokusu na pewno

Część II – administracja MSDE Ograniczenia Instalacja Zarządzanie

Kilka słów o ograniczeniach MSDE: Do 2 GB RAM; max 2 procesory (HT) 8 średniej złożoności zapytań (workload governor) Tylko dla aktywnych połączeń Ograniczenie działa dla danej instancji 16 równoległych instancji (nazwanych) Dane w bazie maks 2 GB; log nie jest ograniczony Brak Analysis Services i Full Text Search Nie publikuje dla replikacji transakcyjnej Replikacja MERGE – tylko węzeł podrzędny Projektowanie bazy: VS.NET; VISIO; Access OSQL jak ktoś lubi W zasadzie już wiadomo wszystko o elementach ze strony .NET – trzeba znaleźć jakąś bazę. MSDE – z wielu powodów wybór ciekawy – zgodna z dużym SQL Server, i z prawami do redystrybucji. Ma jednak kilka ograniczeń Nie więcej niż 2/3 minuty!!!

Sposoby instalacji Wykorzystanie MSM Wywoływanie pliku SETUP.EXE Ale – wtedy też my musimy sami dystrybuować poprawki! HotFix powinny działać… Wywoływanie pliku SETUP.EXE Parametry: /Q – o nic nie pyta /INSTANCENAME=„mojainstancja„ /SECURITYMODE=SQL /SAPWD = “moje tajne hasło” /COLLATION=„nazwa” Plik MSI dodany do własnej instalacji i uruchamiany jako etap Uwagi o SP3a (parametry w linii poleceń) /DISABLENETWORKPROTOCOLS=0 – nie nasłuchuje na żadnych portach (tylko lokalnie); domyślna opcja W jaki sposób instalować – nie jest to takie oczywiste. Ograniczenie licencyjne – baza ma być „dla aplikacji jednego producenta” Dostępne są pliki MSM – własna instalacja

Dystrybucja własnego schematu danych Plik LDF i MDF Skrypty Jeden niewygodny Kilka: Tworzenie tabel Ładowanie danych Tworzenie więzów Tworzenie widoków, SP, funkcji Prawa dostępu Dołączyliśmy do własnej instalacji MSDE – teraz trzeba dołączyć początkową bazę. Aktualizacja – enterprise manager potrafi zapisać „skrypt zmian” – może to wystarczy? Plik LDF i MDF Jak aktualizacje? Skrypty Jeden niewygodny Kilka: Tworzenie tabel Ładowanie danych Tworzenie więzów Tworzenie widoków, SP i okolic Prawa dostępu Lepiej żeby aplikacja a nie program instalacyjny tworzył strukturę bazy Lub oddzielny program

Kilka opcji w bazie Po „CREATE DATABASE” exec sp_dboption N'DD2003', N'autoclose', N‘true' exec sp_dboption N'DD2003', N'trunc. log', N'true' exec sp_dboption N'DD2003', N'autoshrink', N'true' exec sp_dboption N'DD2003', N'auto create statistics', N'true' exec sp_dboption N'DD2003', N'auto update statistics', N'true' Po instalacji MSDE i bazy – warto włączyć kilka opcji które sprawią że baza będzie „samozarządzalna”

Podstawowe operacje administracyjne SQLDMO/TSQL (też – DTS) Warto przeczytać Sql Server Books Online Kopia i odzyskiwanie danych BACKUP DATABASE DD2003 TO DISK='C:\T1‘ RESTORE DATABASE DD2003 FROM DISK='C:\T1‘ Dołączanie/odłączanie bazy sp_attach_db/sp_detach_db DBCC CHECKDB('DD2003') Zastępuje DBCC CHECKALLOC w SQL 7.0 sp_addlogin/ sp_adduser/sp_addrolemember Zostały jeszcze kwestie operacji administracyjnych Nie wiadomo czy dla Yukona będzie coś odpowiadającego MSDE Opakowanie SQLDMO/DTS Warto z mocną nazwą tlbimp.exe sqldmo.dll /keyfile:c:\key\tk.key Można też z poziomu IDE Bez podpisu cyfrowego Używa się tak samo jak z poziomu VB SQLDMO DTS TSQL I tak każde wywołanie SQLDMO to sekwencja TSQL Trochę trudniejsze Yukon… SQLDMO nie będzie rozwijane Nowy model obiektowy Ale TSQL będzie zgodne… Backup – bez dodawania urządzeń itp. Warto przeczytać Sql Server Books Online Kopia i odzyskiwanie danych BACKUP DATABASE DD2003 TO DISK='C:\T1‘ RESTORE DATABASE DD2003 FROM DISK='C:\T1‘ Połączenie np. z bazą master Nie może być dołączonych użytkowników Pobrać z tabeli systemowej i odciąć połączenia Dołączanie/odłączanie bazy sp_attach_db/sp_detach_db DBCC CHECKDB('DD2003') Zastępuje DBCC CHECKALLOC w SQL 7.0 Zasady – login do msde, a potem – user w bazie Addrolemember – też dla zintegrowanego Konfiguracja uprawnień sp_addlogin – logowanie do SQL; hasła itp sp_adduser – użytkownik w danej bazie Logowanie zintegrowane Też trzeba dodać do bazy Dodać login Ale można dodać grupę Pamiętać o prawach dla serwer\ASPNET Role sp_addrolemember – dodaje użytkownika do roli Może po prostu prawa „dla aplikacji” Proste, ale łatwe do obejścia Role db_datawriter,db_datareader Odczyt dowolnych danych z tabel Jak tych praw nie ma -> wymuszenie używania SP  Lepiej: tylko prawa do poszczególnych SP, widoków itp. Dodatkowa kontrola

Uwagi o projekcie, wydajności… Część końcowa Uwagi o projekcie, wydajności… Projektując aplikację warto sobie upraszczać pracę.. Warto trochę pomóc na etapie projektowania bazy danych

Kilka uwaga o wydajności Klucz główny Autoincrement? GUID ! (uniqueidentifier/ klasa Guid ) Kilka wyników w przy jednym zapytaniu CommandBehavior (IDataReader) KeyInfo – brak blokad SingleResult SingleRow Schemat bazy Zamiast wartości NULL – dodatkowy wiersz „puste” Bez PK/więzów… Jakieś pole „naturalnie” unikatowe Autoincrement Synchronizacja… Identity po stronie serwera DataSet AutoIncrement = -1 W InsertCommand zwrócić ID (2 polecenia) Automatyczna aktualizacja wiersza w DataSet GUID – to jest „globalne i unikatowe” – najlepsze Po stronie SQL – typ uniqueidentifier Po stronie .NET – klasa Guid Kolejne uwagi związane z Nie ma potrzeby utrzymywać indeksu PK w DataSet jak dane pochodzą z bazy No ale aktualizacja Kilka wyników w przy jednym zapytaniu CommandBehavior (IDataReader) KeyInfo – brak blokad SingleResult SingleRow Schemat bazy Zamiast wartości NULL – dodatkowy wiersz „puste” - upraszcza raporty, Upraszcza kod INNER JOIN znacznie szybszy niż LEFT JOIN Bez PK?

DataSet a obiekty „logiki „biznesowej Wzorce projektowe Microsoft Data Patterns http://msdn.microsoft.com/practices/type/Patterns/data Data Access Application Block Narzędzia do mapowania O/R LLBLGen PRO SQL Server Centric .NET Code Generator (OlyMars) Oparty o wzorce Gotowe (prawie) Komponenty biznesowe, TreeView Factory, Usługi Web, Styl Object Space BETA! http://www.microsoft.com/france/msdn/olymars 2 min Warto – obejrzeć wzorce projektowe Microsoft Data Patterns http://msdn.microsoft.com/practices/type/Patterns/data Klasy pomocnicze Klasy pomocnicze SQLHelper: ExecuteNonQuery, FillDataSet,ExecuteReader…. Można używać Ściągnąć z MSDN (razem z innymi Application Block) Od razu „tworzą połączenie” itp… Miłe: Cache parametrów do procedur przechowywanych Regenerowanie żmudne (copy/paste…) Ale każdy już ma własne funkcje pomocnicze  Może – własna warstwa DAL Wzorce projektowe Microsoft Data Patterns http://msdn.microsoft.com/practices/type/Patterns/data/ OlyMars – potężne ale niedokończone LLBLGen – na podstawie struktury danych; dobry O/R Mappint OlyMars działa Narzędzia do mapowania O/R LLBLGen PRO SQL Server Centric .NET Code Generator (OlyMars) Oparty o wzorce Gotowe (prawie) Komponenty biznesowe, TreeView Factory, Usługi Web, Styl Object Space Jeszcze z .NET Beta 1 .NET Compact Framework Własne (autorskie) BETA! I nie wspierane http://www.microsoft.com/france/msdn/olymars

Podsumowanie IConnection – pula DataSet – potężny, wersje wartości Nie trzymać „na zaś” DataSet – potężny, wersje wartości Wyszukiwanie, XML IDataReader – bałagan, ale szybki IDataAdapter – od niego zależy komunikacja z bazą DataBinding – doskonałe nie tylko do prezentacji danych MSDE – wygodna baza, którą łatwo można uaktualnić do pełnego SQL w razie potrzeby Trochę pracy w oprogramowaniu części administracyjnej MS Access? Ale warto – w porównaniu z MDB to zupełnie inna klasa rozwiązań Nie wiem czy warto – ale coś zbiorę

Dziękuję za uwagę Pytania: tkopacz@tomaszkopacz.com Po prezentacji…