Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Efektywne wykorzystanie danych w .NET

Podobne prezentacje


Prezentacja na temat: "Efektywne wykorzystanie danych w .NET"— Zapis prezentacji:

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

2 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

3 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…

4 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 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ć!

5 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)

6 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

7 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ć?

8 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

9 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

10 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

11 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

12 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

13 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)

14 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ć

15 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

16 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"]

17 Ł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

18 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: 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: (WriteXML)

19 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

20 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

21 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Ę

22 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);

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

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

25 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

26 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ń

27 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 NVARCHAR(15) … ) AS select * from Customers where is null) AND … select * from Customers where 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

28 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.

29 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));

30 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”

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

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

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

34 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ć…

35 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

36 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

37 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

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

39 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!!!

40 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

41 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

42 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”

43 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

44 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

45 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?

46 DataSet a obiekty „logiki „biznesowej
Wzorce projektowe Microsoft Data Patterns 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! 2 min Warto – obejrzeć wzorce projektowe Microsoft Data Patterns 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 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

47 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ę

48 Dziękuję za uwagę Pytania: Po prezentacji…


Pobierz ppt "Efektywne wykorzystanie danych w .NET"

Podobne prezentacje


Reklamy Google