Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / XML

Simplified XML Based Phone Book Database using LINQ

4.89/5 (6 votes)
24 Nov 2010CPOL6 min read 36.5K   1.5K  
A simplified XML based phone book database using LINQ

Introduction

One day I was thinking how ADO .NET utilizes the database accessibility using dataset and ORM tools. One thing that impresses me was the power of XML technology. Using a plain XML, we can use almost all features of relational database (thanks to their inventor). Even the introduction of XML changed the way programs are build, the structure of configuration files, etc. In .NET, the dataset class can read and write its temporary data to XML. When I was planning to develop a small application using these features, I thought of developing the application using ORM operation.

When I was searching for table mapping from dataset to object, the framework was incapable of doing as LINQ to SQL do. So finally I decided to develop my own application which maps object to dataset data and vice versa and finally persists the data into an XML file.

In this application, I would like to share some information from the application I made using XML as database backend and data table to object mapping on dataset using LINQ.

Background

As I have said in the introduction part, I was looking for data persistence using XML from dataset. Although I found a lot of snips, I found out data manipulation in the dataset using LINQ easy and powerful which I would like to share.

Concepts

The general function of the application is to store contacts detail and retrieve contacts from the database, in our case the XML file. The application is designed with separation of layers into three layered architecture, where each layer is separated from the other.

Image 1

  • The data layer where the data is persisted on XML file
  • The data access layer and Business layer, in our case the DAL and BL is defined in the DAL class where data is mapped from XML file across the dataset to the contact object as well as data is saved from the active contact class through Dataset to XML.
  • The UI where the data presentation is developed using any technology such as Windows Forms, WPF, web, etc. In our case, I develop the UI layer using Windows Forms as an illustration.

Here the main concepts behind the code lies here, once data is loaded from the XML file, it is loaded to dataset, then from the dataset the data is mapped to appropriate contact objects. Like any other ORM tools such as LINQ to SQL, we are doing the mapping manually from dataset to objects. After that, once objects are mapped, the business functionality is manipulated using LINQ on the objects to perform various operations.

Using the Code

Here the code is divided into two - the first part is designing the data access layer class with business layer which performs all the operations. The second part is the UI which is designed in such a way as to perform various operations of the phonebook application. Here in my application, although I have used only Windows Form for the UI layer, it is easily extended to other UIs like WPF, Web Forms, etc. The DAL layer consists of the contact class with dataset:

Image 2 Image 3

Data Reading

ReadData() method reads data from the XML file to the dataset, and then data row in the dataset is mapped to contact object.

C#
//read  data from the xml file and
  private  void ReadData()
  {
  try
  {
  ds.Clear();
  Contacts.Clear();
  //checks  whether the file exists otherwise it create blank file
  if  (!System.IO.File.Exists(FileName))
  {
System.IO.File.Create(FileName);
  }
  else
  {//read  data to dataset then map the data row to contact object
  ds.ReadXml(FileName, XmlReadMode.IgnoreSchema);
  Contact c;
  foreach (DataRow dr in ds.Tables[0].Rows)
  {

  c = new Contact() { SN  = Convert.ToInt32(dr[0]),
  Name =  dr[1].ToString(), Tele = dr[2].ToString(),
  Email = dr[3].ToString(), Gender = Convert.ToChar(dr[4]) };
  //added to the contacts  collection
  Contacts.Add(c);
  }
  }
  }
  catch  (Exception ex)
  {
  Console.WriteLine(ex.Message);
  //throw  (ex);
  }
} 

Here the point is that the dataset is used in mapping the data from XML to the contact object. Finally the contacts collection holds the data information of contact object, at the point querying the object using LINQ becomes easy.

Business Operation

Now let us look at other typical operations once the data are loaded into the contacts list, say we want to get all contacts.

C#
//using simple LINQ operation we can get all the contacts
  public  List<Contact>  GetContact()
  {
  var  cont = (from cc in  Contacts
  orderby cc.SN
  select cc).ToList();
  return  cont;

  }
  //for  single contact
  public Contact GetContact(int  id)
  {
  return  Contacts.Where(cc => cc.SN == id).SingleOrDefault();
}

Again if we look at the typical CRUD operation, the data manipulation is also maintained using a simple operation. However, unlike the typical ADO.NET based database application, all operations are done simply on the list.

C#
//to delete contact from the list
public  Boolean DeleteContact(int id)
{    //remove the contact with the id from the  contacts list
return  Contacts.Remove(GetContact(id))?true:false;
}
//to add contact into list
public void AddContact(Contact  c)
{
//add the  new contact to the Contacts list
Contacts.Add(c);
}
//clear the  list
public void clearlist()
{
//clears the  contacts from the collection
Contacts.Clear();
}

Data Saving

Finally, only the Contacts object list is persisted to the XML file when the Save() method is called. This look like a typical LINQ to SQL operation, where data is saved to the database only when the submitchange() method of the datacontext object is called. Here our save method looks like:

C#
//maps  the object from the contacts list to datarow in the dataset
  //the dataset  is saved to the xml file
  public Boolean Save()
  {

  try
  {
  ds.Clear();
  DataRow  dr;
  foreach  (Contact c in  Contacts)
  {
  dr =  ds.Tables[0].NewRow();
  dr[0] = c.SN;
  dr[1] = c.Name;
  dr[2] = c.Tele;
  dr[3] = c.Email;
  dr[4] = c.Gender;
  ds.Tables[0].Rows.Add(dr);
  }

  ds.WriteXml(FileName, XmlWriteMode.IgnoreSchema);
  return  true;
  }
  catch  (Exception ex) {

  return  false;
  }  

Here the point is reverse to the read operation, where the data is mapped from object to datarow, then finally the data is saved from the dataset to XML file via WriteXml() method of dataset object. Finally, the layer is compiled as class library to be referenced from the UI layer.

The UI Layer

Since the business operation layer is done on the DAL, the operation of UI layer is simply to present the data. The main operation is just referencing the class layer and implements the functionality of the phonebook application in your favorite UI. In my case, I have chosen to implement using the Windows Forms although it is extendable with a little similar manner to web application and WPF.

Image 4

When the Windows Form is loaded, the contacts data is bound to the bindingsource, where the binding source is used throughout the application for binding the Windows controls on the form and the data grid.

C#
using  Book;

//....
  private  void Form1_Load(object  sender, EventArgs e)
  {
  //gets all contact in object form
  bindingSource1.DataSource =  dall.GetContact();
  bindsource();
  bindControls();
  }
  public  void bindsource()
  { dgvaddress.DataSource =  bindingSource1;
  }

Many of the binding source operations are pretty straight forward. I use simply like methods of the binding source like:

  • Bindingsource1.MoveFirst()
  • Bindingsource1.MoveNext()
  • Bindingsource1.AddNew()

etc.

Finally when data editing and manipulation is finished, our DAL class method save is called to persist the data.

C#
private  void btnsave_Click(object  sender, EventArgs e)
  { //save data  in the grid to xml file
  AddGridValuetolist();
  if  (dall.Save())
  MessageBox.Show("success");
  else
  MessageBox.Show("error");
} 

When the save button is clicked, first the data in the grid is mapped to the contact list, then each contact is added to Contacts list in the DAL layer class, after that, the save method of the DAL class is called to save the list data into the XML file.

C#
// adds the  datarow from the grid to contact list
public void AddGridValuetolist()
{
Contact  c;
dall.clearlist();
foreach  (DataGridViewRow dr in  dgvaddress.Rows)
{
if  (dr.Cells [2].Value != null)
{ //mapping  from datagridviewrow into contact object
c = new Contact()
{
SN = Convert.ToInt32(dr.Cells[0].Value),
Name = Convert.ToString(dr.Cells[1].Value),
Tele = Convert.ToString(dr.Cells[2].Value),
Email = Convert.ToString(dr.Cells[3].Value),
Gender = Convert.ToChar(dr.Cells[4].Value)
};
dall.AddContact(c);
}
}
}

Point of Interest

As I have explained in detail, the whole point of the article is focused on creating object to dataset mapping. Here we have created our own way of object persistence to database and data from the XML file to object via the dataset. In this case, if you are familiar with LINQ to SQL, the datacontext class creates a mapping of tables in database to objects and vice versa. In our application, the mapping of objects to data in XML is done using dataset and LINQ queries. When I was developing the application, my main intent was to develop XML based database. However, when I look to some stuff, I couldn’t find any way ORM like tool to work against dataset. Still the LINQ to dataset provides me data listing operation just like any type collection with the data table and data row, whereas the capability for object mapping like in LINQ to SQL is unavailable in LINQ to dataset. This leads me to develop an ORM based application using LINQ to Dataset finally to XML file.

History

  • 24th November, 2010: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)