Search Forum
(57415 Postings)
Search Site/Articles

Archived Articles
712 Articles

C# Books
C# Consultants
What Is C#?
Download Compiler
Code Archive
Archived Articles
Advertise
Contribute
C# Jobs
Beginners Tutorial
C# Contractors
C# Consulting
Links
C# Manual
Contact Us
Legal

GoDiagram for .NET from Northwoods Software www.nwoods.com


              
Printable Version

Using ADO.NET Database 1 for beginners
By Hüseyin Altindag

Introduction

This is a simple ADO.NET database application that returns results
from a database table, writes the output to a DataGrid and TextBoxes,
and uses Buttons to navigate through records.

It is including:
1. Connection to a ADO.NET database
2. Use of a DataSet to fill with records
3. Use of a DataAdapter to load data into the DataSet
4. Display data in a DataGrid
5. DataBindings for TextBoxes
6. Use of the CurrencyManager
7. Navigation through records with Next,Previous,Last,First buttons.

This project was developed using Visual Studio.NET 2003 and Microsoft Access
on Windows XP Pro

What is ADO.NET ?

ADO.NET is the new database technology of the .NET(DotNet) platform,
and it builds on ADO(ActiveX Data Objects).
ADO is a language-neutral object model that is
the keystone of Microsoft's Universal Data Access strategy.
ADO.NET defines DataSet and DataTable objects which are
optimized for moving disconnected sets of data across intranets and Internets,
including through firewalls. It´s also including the traditional Connection and
Command objects, as well as an object called a DataReader that resembles
a forward-only, read-only ADO recordset.

If you create a new application your application requires
most of the time some form of data access.
ADO.NET provides data access services in the Microsoft .NET Platform.
You can use ADO.NET to access data by using the new .NET Framework data providers which are
- Data Provider for SQL Server(System.Data.SqlClient).
- Data Provider for OLEDB(System.Data.OleDb).
- Data Provider for ODBC(System.Data.Odbc).
- Data Provider for Oracle(System.Data.OracleClient).

ADO.NET is a set of classes that expose data access services to the .NET developer.
The ADO.NETclasses are found in System.Data.dll and integrated with XML classes in System.Xml.dll.

There are two central components of ADO.NET classes:
the DataSet, and the .NET Framework Data Provider.

Data Provider is a set of components including
the Connection object(SqlConnection, OleDbConnection, OdbcConnection, OracleConnection),
the Command object(SqlCommand, OleDbCommand, OdbcCommand, OracleCommand),
the DataReader object(SqlDataReader, OleDbDataReader,OdbcDataReader, OracleDataReader),
and the DataAdapter object(SqlDataAdapter, OleDbDataAdapter, OdbcDataAdapter, OracleDataAdapter).

DataSet object represents a disconnected cache of data
which is made up of DataTables and DataRelations that
represent the result of the command.

The ADO.NET Object Modell



1. Connection to a ADO.NET database

Before working with a database, you have to add (here) the OleDb .NET Data Provider namespace,
by placing the following at the start of your code module:
using System.Data.OleDb;
Similarly for the SqlClient .NET Data Provider namespace:
using System.Data.SqlClient;
The using statement should be positioned first in your code.
Now we have to declare a connection string pointing to a MS Access database "PersonDatabase.mdb".
public string conString=@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=..\..\PersonDatabase.mdb";
The database should be in the specified path, otherwise you should change the path accordingly.

The next step is to create an OleDbConnection object. We pass then the connection string to this OleDbConnection object.
You can code now to create a new ADO.NET Connection object
in order to connect to an OLE DB provider database .

OleDbConnection con = new OleDbConnection(conString);
You can also explicitly reference declared objects if you don’t mind typing a lot.
System.Data.OleDb.OleDbConnection con = new System.Data.OleDb.OleDbConnection(conString);
//
//1.Connection to a database
//using declaration for OLE DB
using System.Data.OleDb;
//specify the ConnectionString property
public string conString=@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=..\..\PersonDatabase.mdb";
//Initializes a new instance of the OleDbConnection
OleDbConnection con = new OleDbConnection (conString);


2. DataSet

The DataSet is similar to an array of disconnected Recordset objects.
It supports disconnected data access and operations, allowing greater scalability
because you no longer have to be connected to the database all the time.
DataSet is a copy of a extracted data being downloaded and
cached in the client system.

DataSet object is made up of 2 objects:
-DataTableCollection Object containing null or multiple DataTable objects(Columns, Rows, Constrains)
-DataRelationCollection Object containing null or multiple DataRelation objects
which establishes a parent/child relation between two DataTable objects.
//Create a DataSet
DataSet dset = new DataSet();

There are two types of DataSets:
1. Typed dataset
2. Untyped dataset

1. Typed dataset is derived from the base DataSet class and then uses information
in an XML Schema file (.xsd file) in order to generate a new class.
Information from the schema (tables, columns, and so on) is generated and compiled
into this new dataset class as a set of first-class objects and properties.

Typed dataset is easier to read.It´s also supported by IntelliSense in the Visual Studio Code Editor.
At compile time, it has type checking so that there are less errors in assigning values to dataset members.
Using Typed dataset has many advantages.
Example:
The following code accesses the CustomerID column in the first row of the Customers table
string str;
str=dset.Customers[0].CustomerID;


2. Untyped dataset is not defined by a schema, instead, you have to add tables, columns, and other elements to it yourself,
either by setting properties at design time or by adding them at run time.
For example : scenario: if you don´t know in advance what the stucture of your program is
that interacting with a component that returns a dataset.
the equivalent code above for Untyped dataset is:
string str;
str=(string)dset.Tables["Customers"].Row[0].["CustomerID"];

A dataset is a container; therefore, you have to fill it with data.
You can populate a dataset in a variety of ways;
# by using Fill method
# by creating DataRow objects and adding them to the table's Rows collection(only at run time).
# Read an XML document or stream into the dataset
# Merge (copy) the contents of another dataset

3. DataAdapter

DataAdapter object is like a bridge that links the database
and a Connection object with the ADO.NET-managed DataSet object
through its SELECT and action query Commands.

It specifies what data to move into and out of the DataAdapter.
Often this takes the form of references to SQL statements or stored procedures
that are invoked to read or write to a database.
The DataAdapter provides four properties that allow us to control
how updates are made to the server:
SelectCommand, UpdateCommand, InsertCommand, and DeleteCommand.
The four properties are set to Command objects that are used when data is manipulated.

The DataAdapter includes 3 main methods:
- Fill (populates a DataSet with data)
- FillSchema (queries the database for schema information that is necessary to update)
- Update (to change the database DataAdapter calls the DeleteCommand,
the InsertCommand and the UpdateCommand property)
For instance , when we call the DataAdapter's Fill method to retrieve
data from a data source and pour it into a DataSet, the Command object in the
SelectCommand property is used. The DataAdapter is the gatekeeper that sits
between our DataSet and the data source.

//Create an instance of a OleDbDataAdapter by passing OleDbConnection object and select.. query
OleDbDataAdapter dAdapter = new OleDbDataAdapter ("select * from PersonTable", con );
//fill the DataSet with records from the table "PersonTable"
dAdapter.Fill(dSet,"PersonTable");

Here is the method used in this project to get data connection, DataSet and DataAdapter.
This method is in the file "DataAccessTierClass.cs".

public bool fnGetDataConnection()
{
     try {
         con =new OleDbConnection(conString);
         dAdapter=new OleDbDataAdapter("select * from PersonTable", con);
         dSet=new DataSet();
         //refreshes rows in the DataSet
         dAdapter.Fill(dSet,"PersonTable");
      }catch(Exception ex) {
            MessageBox.Show("Error : "+ex.Message);
            //connectection failed
            return false;
      } //try-catch
      //connection ok!
      return true;
}

4. Display data in a DataGrid

The Windows Forms DataGrid control displays data in a series of rows
and columns. The Windows Forms DataGrid control provides a user interface
to ADO.NET datasets. It displays tabular data and allows
for updates to the data source.
When you set DataGrid control to a valid data source, the control
will be automatically populated, creating columns and rows based
on the shape of the data.
You can use the DataGrid control for displaying either a single table
or the hierarchical relationships between a set of tables.
Iy you want to work with the DataGrid control, DataGrid should be
bound to a data source by using
- the DataSource and
- DataMember properties at design time
or
- the SetDataBinding method at run time.

Here is the binding to the DataGrid control with DataSet I used in this project.
this . dataGrid1 . DataSource = datc . dSet . Tables["PersonTable"];

You can only show one table in the DataGrid at a time.
If you define a parent-child relationship between tables,
you can navigate between the related tables to select
the table you want to display in DataGrid control.
Example:
dset.Relations.Add("CustomerOrders",
dset.Tables["customers"].Columns["CustomerID"],
dset.Tables["orders"].Columns["CustomerID"]);
//here you can use one of the following
this.dataGrid1.DataSource=dset.Tables["customers"];
OR
this.dataGrid1.SetDataBinding(dset,"customers");

customers: Parent table
orders      : Child table
CustomerID in Orders is a foreign key referring to CustomerID primary key in Customers table.

If you update the data in the bound DataSet through any mechanism,
the DataGrid control reflects the changes.
You can update the data in the DataSet through the DataGrid control,
if the data grid and its table styles and column styles
have the ReadOnly property set to false.

There are 4 most typical valid data sources for the DataGrid

  • DataTable class
  • DataView class
  • DataSet class
  • DataViewManager class
5. DataBindings for TextBoxes

DataBinding is the ability to bind some elements of a data source with some graphical elements of an application.
The data in Windows Form is bound by calling DataBindings.
Windows Forms allow you to bind easily to almost any structure that contains data.
Windows Forms Controls support 2 types of data binding:
1.Simple Data Binding
2.Complex Data Binding

Simple Data Binding allows you to display a single data element,
such as a column value from a dataset table, in a control.
You can simple-bind any property of a control to a data value.
Simple Data Binding can be performed either at design time
using DataBindings property of a control OR dynamicall at run time.
This is the type of binding typical for controls such as a TextBox control
or Label control that displays typically only a single value.
Example:
// Simple DataBinding for TextBox "textBox1"
textBox1.DataBindings.Add("Text", dataset, "studentTable.studentID");
The control "textBox1" is bound to the "studentID" column of a table "studentTable"
on the DataSet(dataset) through the BindingContext object.

Complex data binding is the ability of a control to bind to more than one
data element, typically more than one record in a database,
or to more than one of any other type of bindable data element.
DataGrid, ListBox and ErrorProvider controls support Complex data binding.

Here is the method used in this project to bind all TextBoxes:
private void fnGetDataBindingForTextBoxes()
{
      this.textboxFirstname.DataBindings .Add("Text", datc.dSet.Tables["PersonTable"],"FirstName");
      this.textboxLastname.DataBindings .Add("Text", datc.dSet.Tables["PersonTable"],"LastName");
      this.textboxTitle.DataBindings .Add("Text", datc.dSet.Tables["PersonTable"],"Title");
      this.textboxCity.DataBindings .Add("Text", datc.dSet.Tables["PersonTable"],"City");
      this.textboxCountry.DataBindings .Add("Text", datc.dSet.Tables["PersonTable"],"Country");
}

6. Using of the CurrencyManager

Every Windows Form has a BindingContext object keeping track
of all the CurrencyManager objects on the Windows Form.
CurrencyManager keeeps track of the position in the data source.
When you bind a data object to a control(i.e TextBox), a CurrencyManager object
is automatically assigned. If you bind several controls to the same data source,
they share the same CurrencyManager.


Example:
* If you want to know how many records are in a data table, you simply
query the BindingContext object's Count property.
this.BindingContext[dataset1,"PersonTable"].Count - 1 ;
*If you want to get the current position from the BindingContext object
this.BindingContext[dataset1, "PersonTable"].Position + 1;

Here is the method I used to initialize the CurrencyManager for the table "PersonTable".
public void fnSetCurrencyManager()
{
     currManager = (CurrencyManager)this. BindingContext [ datc.dSet.Tables["PersonTable"] ] ;
}

7. Navigation through records with Next,Previous,Last,First buttons

As soon as you get the data populated in the DataGrid,
you can navigate through records by using Next,Previous,Last,First buttons
or by clicking the rows of the DataGrid or by using
the arrow keys (UP ARROW and DOWN ARROW).

If the DataGrid is currently displaying data, none of the
standard keyboard events are raised for the navigation keys.
You can still use Up and Down arrow keys to navigate in the DataGrid
but, because no keystrokes captured, you don´t get the record
position in the StatusBar.

In order to capture keystrokes on the DataGrid, you have to override
the ProcessCmdKey method that processes a command key.
I haven´t implemented that because it would be here a bit too much coding.
Maybe in the next second part where you manupulate data in TextBoxes and in the DataGrid.

Now back to the buttons:
When you click First button, position will be set to 0(zero) because the first row starts by zero.
currManager.Position=0; and
  • Disable First and Previous buttons because there is no previous record in the data source.
  • Enable Next and Last buttons because there are records forwards.
When you click Next button, position in the data is increased by 1 and moved to the next row.
currManager.Position +=1; and
  • Enable First and Previous buttons as long as there are forwards records.
  • Otherwise Disable Next and Last buttons which means you reached the end of the records.
When you click Previous button, position in the data is decreased by -1 and moved to the previous row.
currManager.Position -=1; and
  • Enable Next and Last buttons as long as there are records backwards.
  • Otherwise Disable First and Previous buttons which means you reached the beginning of the records.
When you click Last button, position in the data is set to the last record(row).
this.currManager.Position=this.currManager.Count-1; and
  • Disable Next and Last buttons because there are no records forwards any more .
  • Otherwise enable First and Previous buttons so that you can navigate backwards.
To enable and disable the buttons I use the function(fn)/method fnEnableDisableButtons
with 4 parameters(2 buttons, string for StatusBar, bool for true=enabling, false=disabling)

private
void fnEnableDisableButtons(Button bt1, Button bt2, string str, bool b)
{
      bt1.Enabled=b;
      bt2.Enabled=b;
      this.statusBar1.Text=str;
}

Download Source

In conclusion

I tried to show the basics of the ADO.NET Database to the beginner
how to use the ADO.NET in a database application
and to keep the code as readable as possible.
I intend to implement in a new next version the data manupulation
on the DataGrid and TextBoxes(Delete, Save/Update, Search, Add)

I hope it can help you understand a bit what ADO.NET is.

Good coding

Hüseyin Altindag