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.
- 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
:
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.
private void ReadData()
{
try
{
ds.Clear();
Contacts.Clear();
if (!System.IO.File.Exists(FileName))
{
System.IO.File.Create(FileName);
}
else
{
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]) };
Contacts.Add(c);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
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
.
public List<Contact> GetContact()
{
var cont = (from cc in Contacts
orderby cc.SN
select cc).ToList();
return cont;
}
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.
public Boolean DeleteContact(int id)
{
return Contacts.Remove(GetContact(id))?true:false;
}
public void AddContact(Contact c)
{
Contacts.Add(c);
}
public void clearlist()
{
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:
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.
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.
using Book;
private void Form1_Load(object sender, EventArgs e)
{
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.
private void btnsave_Click(object sender, EventArgs e)
{
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.
public void AddGridValuetolist()
{
Contact c;
dall.clearlist();
foreach (DataGridViewRow dr in dgvaddress.Rows)
{
if (dr.Cells [2].Value != null)
{
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