piątek, 18 stycznia 2013

70-516 Serializacja obiektów ADO.NET, bindowanie do kontrolek

W tym artykule skupimy się na serializacji obiektów ADO.NET, przechowywaniu w kolumnach typów złożonych oraz bindowaniu w aplikacjach do danych. 

Serializacja
Obiekt DataTable możemy zapisać do pliku XML, jak i zwykłego strumienia. Metoda która do tego służy to WriteXml:

Code:
simpleDataSet.Tables["Client"].WriteXml("plik.xml");

Nazwa pliku nie może zawierać spacji, a jeżeli nawet podalibyśmy nazwę ze spacjami zostanie ona zmieniona na znak podkreślenia - "_".
Zawartość generowanego XMLa można kontrolować za pomocą własnej schemy dla XMLa oraz ustawiając odpowiednie właściwości kolumn obiektu DataTable.
Za pomocą właściwości ColumnMapping możemy ustawić czy dana kolumna ma być atrybutem, elementem czy też w ogóle może się nie pojawić:

Code:
clientTable.Columns["Id"].ColumnMapping = MappingType.Attribute;

Możliwe wartości typu wyliczeniowego ColumnMapping:
  • Attribute - kolumna jako atrybut
  • Element - kolumna jako element
  • Hidden - dane z tej kolumny nie zostaną zapisane do XMLa
  • SimpleContent - dane zapisane są jako zwykły string bez dodatkowych tagów

Po zapisaniu danych należy zapisać schemę - XSD. Plik ten zawiera także XML, który jest definicją typów danych użytych w DataTable:

Code:
simpleDataSet.Tables["Client"].WriteXmlSchema("schema.xml");

Dane możemy także zapisać razem ze schemą tabeli w jednym pliku. Wybór należy do nas.
Dane wczytuje za pomocą metody ReadXml. Jeżeli schema była w innym pliku wczytujemy ją za pomocą metody ReadXmlSchema:

Code:
            DataTable dt = new DataTable();
            dt.ReadXmlSchema("schema.xml");
            dt.ReadXml("plik.xml");


Obsługa DataSet-u przebiega w ten sam sposób. Przykładowe zapisanie i wczytanie danych z plików XML wygląda następująco:

Code:
            simpleDataSet.WriteXml("dataset_data.xml");
            simpleDataSet.WriteXmlSchema("dataset_schema.xml");

            DataSet ds = new DataSet();
            ds.ReadXmlSchema("dataset_schema.xml");
            ds.ReadXml("dataset_data.xml");



DataSet DiffGram
DiffGram to zserializowany DataSet do pliku zawierający dane o wersji wiersza. Rozwiązanie to może się przydać w przypadku gdy rzadko łączymy się z bazą danych i przechowujemy DataSet lokalnie na dysku. Jeżeli dokonamy zmian, następnie zapiszemy je do pliku a później odczytamy, stracimy informacje o zmianach. Nie będziemy w stanie uaktualnić danych w bazie danych.
Przykład tworzenia DiffGram-a:

Code:
simpleDataSet.WriteXml("Diff_Gram.xml", XmlWriteMode.DiffGram);

Wczytując (deserializując) dane należy podać odpowiednią wartość XmlReadMode:
  • Auto - plik XML zostanie sprawdzony i zostanie wybrana najlepsza metoda odczytu
  • DiffGram - zachowuje się w taki sam sposób jak metoda Merge
  • Fragment - wczytuje plik XML jako część, oznacza to że plik XML może zawierć wiele elementów głónych
  • IgnoreSchema - nie deserializuje schematu
  • InferSchema - schemat DataSet-u jest tworzony na podstawie danych zawartych w pliku
  • InferTypedSchema - schemat DataSet-u tworzony jest na podstawie danych zawartych w pliku, jeżeli nie jest w stanie jednoznacznie wyznaczyć typu - użyty zostanie typ string
  • ReadSchema - wczytuje dane wraz z schematem


Binarna serializacja DataSet 
Serializacja binarna przydatna jest w przypadku gdy chcemy aby plik wynikowy był jak najmniejszy. Serializacja przebiega w taki sam sposób. Należy jednak wcześniej ustawić właściwość RemotingFormat na Binary. Jeżeli tego nie zrobimy, plik wynikowy będzie zawierał w swoim wnętrzu plik XML.
Serializacja powinna wyglądać w następujący sposób:

Code:
            simpleDataSet.RemotingFormat = SerializationFormat.Binary;
            using (var fs = new FileStream("dane.bin", FileMode.Create))
            {
                var binaryFormatter = new BinaryFormatter();
                binaryFormatter.Serialize(fs, simpleDataSet);
            }



Odczyt danych za pomocą DataTableReader
Dane z DataTable oraz DataSet można odczytać za pomocą klasy DataTableReader. Klasa ta pozwala tylko na odczyt wierszy za pomocą metody Read. Jeżeli wiersz zostanie dodany w trakcie iteracji po danych to w zależności od tego czy zostanie dodany przed wskaźnikiem aktualnej pozycji czy też za nim zostanie wyświetlony bądź też nie. Kiedy DataTableReader dojdzie do końca tabeli, metoda Read zwróci null. Po tej operacji dodanie danych nie spowoduje ich odczytania.
Jeżeli iterujemy DataSet, dane będą odczytywane najpierw z pierwszej tabeli a następnie za pomocą metody NextResult możemy przejść do kolejnej tabeli.
Przykład odczytu DataSet:

Code:
            DataTableReader dr = simpleDataSet.CreateDataReader();
            while (dr.Read())
            {
                Console.WriteLine(dr["Id"] + " " + dr["FirstName"]);
            }
            dr.NextResult();
            while (dr.Read())
            {
                Console.WriteLine(dr["Id"] + " " + dr["CreationDate"]);
            }



Przechowywanie typów złożonych w kolumnach DataTable
W kolumnie DataTable można przechowywać typy specjalne, takie jak obiekty klasy, dane XML. Kolumna taka może przechować dowolny typ który jest referencyjny - wyjątkiem jest klasa string.
Przykład w jaki sposób można przechować w kolumnie obiekty typu Computer w tabeli User:

Code:
            DataTable dtSpecializedColumn = new DataTable("User");
            dtSpecializedColumn.Columns.Add("Id", typeof (int));
            dtSpecializedColumn.Columns.Add("FirstName", typeof (string));
            dtSpecializedColumn.Columns.Add("LastName", typeof (string));
            dtSpecializedColumn.Columns.Add("Computer", typeof (Computer));

            dtSpecializedColumn.Rows.Add(new object[]
                            {
                                1, "Jacek", "Kowalski",
                                new Computer {Id = 1, GraphicCard = "Ati", Processor = "Intel", UsbAmount = 10}
                            });
            Console.WriteLine(((Computer)dtSpecializedColumn.Rows[0]["Computer"]).UsbAmount);



Bindowanie w WindowsForms
Kontrolki w WindowsForms można bindować do obiektów implementujących IList, IListSource, IBindingList, IBindingListView. Właściwości które używamy podczas bindowania:
  • DataSource - źródło implementujące jeden z wcześniej wymienionych interfejsów
  • DataMember - jeżeli źródło zawiera wiele elementów np. DataSet zawiera wiele obiektów DataTable, należy wskazać, którą tabelę chcemy wyświetlić. 
  • DisplayMember - dla kontrolek typu lista wskazuje która kolumna ma być wyświetlana 
  • ValueMember - wskazuje, wartość która zostanie pobrana z kontrolki typu lista; najczęściej jest to klucz główny

Bindowanie w ASP.NET
W przypadku ASP.NET, właściwości w kontrolkach webowych mają takie same znaczenie jak dla WindowsForms.
Należy pamiętać, że po bindowaniu musi zostać wywołana metoda DataBind. Jeżeli tego zrobimy dane nie zostaną dodane do kontrolki.


Bindowane w WPF
W przypadku WPFa możemy bindować do praktycznie dowolnego obiektu. Główną właściwością do której następuje bindowanie jest ItemsSource.


Źródła do pobrania: https://skydrive.live.com/redir?resid=BCCBFB57B3C672D0!150&authkey=!AJunqZlTIcRyX-s

Brak komentarzy:

Prześlij komentarz