Сериалізація і десериалізація DataSet об'єктів

вторник, 18 ноября 2008, Александр Краковецкий

Об'єкт DataSource має досить прості, але в той же час потужні засоби для роботи з XML форматом. Розглянемо їх детальніше.

Напишемо функцію GetDataSet, яка буде створювати структуру і зв'язки для нашого DataSet:

private DataSet GetDataSet()
{
  DataSet companyData = new DataSet("CompanyList");

  DataTable company = companyData.Tables.Add("Company");
  company.Columns.Add("Id", typeof(Guid));
  company.Columns.Add("CompanyName", typeof(string));
  company.PrimaryKey = new DataColumn[] { company.Columns["Id"] };
   
  DataTable employee = companyData.Tables.Add("Employee");
  employee.Columns.Add("Id", typeof(Guid));
  employee.Columns.Add("CompanyId", typeof(Guid));
  employee.Columns.Add("FullName", typeof(string));
  employee.PrimaryKey = new DataColumn[] { employee.Columns["Id"] };

  companyData.Relations.Add("Company_Employee", company.Columns["Id"], employee.Columns["CompanyId"]);

  return companyData;
}

Потім додамо по одному запису в кожну таблицю:

DataSet ds = this.GetDataSet();
Guid guid = Guid.NewGuid();

DataRow newCompanyRow = ds.Tables["Company"].NewRow();
newCompanyRow["Id"] = guid;
newCompanyRow["CompanyName"] = "MyCompany";
ds.Tables["Company"].Rows.Add(newCompanyRow);

DataRow newEmployeeRow = ds.Tables["Employee"].NewRow();
newEmployeeRow["Id"] = Guid.NewGuid();
newEmployeeRow["CompanyId"] = guid;
newEmployeeRow["FullName"] = "Employee full name";
ds.Tables["Employee"].Rows.Add(newEmployeeRow);

1. Збереження даних в XML файлі

ds.WriteXml(MapPath("~/CustomerList.xml"));

Файл матиме вигляд:



 
  3f860d5b-d978-48ec-a0a5-d1da3068654a
  MyCompany
 

 
  57e4759b-1e06-4182-ab73-409d6d4db6a6
  3f860d5b-d978-48ec-a0a5-d1da3068654a
  Employee full name
 

Як ми бачимо, спочатку у нас записана інформація про Company, далі - про Employee. Це не зручно для нас, так як логічно було б мати Employee в Company.

Для цього в функції GetDataSet додамо наступну строку і перезапустим код:

companyData.Relations["Company_Employee"].Nested = true;

Тепер ми побачимо наступний XML файл:



 
  6df47d77-cac0-4cc6-bd0c-f96b95f569c7
  MyCompany
  
   048c7cc2-1d18-478c-be77-d38c7326b5c4
   6df47d77-cac0-4cc6-bd0c-f96b95f569c7
   Employee full name
  

 

Для того, щоб XML файли не містили дані в окремому ноді, допишемо такий код перед записом даних в файл:

foreach (DataTable dt in ds.Tables)
{
  foreach (DataColumn dc in dt.Columns)
  {
    dc.ColumnMapping = MappingType.Attribute;
  }
}

Тепер матимо на виході такий файл:



 
  
 

2. Збереження схеми даних в XML файлі

Для того, щоб зберегти XSD-схему без даних, необхідно виконати такий код:

ds.WriteXmlSchema(MapPath("~/CustomerList.xsd"));

На виході матимо XSD-файл:



 
  
   
    
     
      
       
        
         
         
         
        

       

      

      
      
     

    

   

  

  
   
   
  

  
   
   
  

  
   
   
  

 

Для збереження даних і схеми в файл, необхідно виконати:

ds.WriteXml(MapPath("~/CustomerList.xml"), XmlWriteMode.WriteSchema);

3. Збереження всіх станів даних

Додамо такий код перед тим, як згенерити XML файл:

ds.Tables["Employee"].Rows[0]["FullName"] = "John Smith";

І запишемо файл в режимі DiffGram:

ds.WriteXml(MapPath("~/CustomerList.xml"), XmlWriteMode.DiffGram);

На виході матимемо:



 
  
   
  

 


Як ми бачимо попереднє значення "Employee full name" не збереглось, хоча додаткової інформації зявилося багато.

Причина в тому, що DataSet нічого не знає, а що було раніше, і що змінилося. Для того, щоб DataSet дізнався про це, необхідно викликати

ds.AcceptChanges();

DataSet збереже попередній стан і порівняє його з новим, а на виході отримаємо вже розширений файл:



 
  
   
  

 

 
  
 

Найкращим чином було б зберегти окремо XSD-схему і XML з даними для зручної подальшої роботи.

4. Отримання даних з XML і XSD файлів

Для отримання даних назад використовуються методи ReadXml і ReadXmlSchema:

DataSet companyList = new DataSet();
companyList.ReadXmlSchema(MapPath("CompanyList.xsd"));
companyList.ReadXml(MapPath("CompanyList.xml"));

Контролу, який буде відображати дані (наприклад, GridView), необхідно задати companyList як DataSource і назву таблиці як DataMember:

gridCompany.DataSource = companyList;
gridCompany.DataMember = "Company";

gridEmployee.DataSource = companyList;
gridEmployee.DataMember = "Employee";

gridCompany.DataBind();
gridEmployee.DataBind();

Коли ви читаєте дані з файлу, то за замовчуванням схема ігнорується. Змінити це можна, задавши XmlReadMode в методі ReadXml.

5. Сериалізація і десериалізація у вигляді бінарних даних

Для даного способу необхідно задати для DataSource значення RemotingFormat:

companyList.RemotingFormat = SerializationFormat.Binary;

Запис в бінарний файл:

using (FileStream fs = new FileStream(MapPath("CompanyList.bin"), FileMode.Create))
{
    BinaryFormatter fmt = new BinaryFormatter();
    fmt.Serialize(fs, companyList);
}

Для протилежної дії необхідно виконати:

using (FileStream fs = new FileStream(MapPath("CompanyList.bin"), FileMode.Open))
{
    BinaryFormatter fmt = new BinaryFormatter();
    companyList = fmt.Deserialize(fs) as DataSet;
}

Загалом, DataSet є потужним засобом для роботи з даними і, зокрема, для сериалізації і десериалізації.

Компании из статьи


Microsoft Украина


Сайт:
http://www.microsoft.com/ukr/ua/

Microsoft Украина Украинское подразделение компании Microsoft.

Ищите нас в интернетах!

Комментарии

Свежие вакансии