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