Chapter 6

Download as pdf or txt
Download as pdf or txt
You are on page 1of 15

𝐂𝐡𝐚𝐩𝐭𝐞𝐫 𝟔

𝐃𝐚𝐭𝐚𝐛𝐚𝐬𝐞 𝐩𝐫𝐨𝐠𝐫𝐚𝐦𝐦𝐢𝐧𝐠
The ADO.NET architecture
Most applications in most databases can’t be developed without having an interaction with the
database. Databases serve the purpose of data storage so the data can be retrieved later via either
a SQL query or a database application. Almost every software application running interacts with
either one or multiple databases. Therefore, the front end needs a mechanism to connect with
databases, and ADO.NET serves that purpose. Most of the .NET applications that require database
functionality are dependent on ADO.NET.

.NET, developers used data access technologies such as ODBC, OLE DB, and ActiveX Data
Object (ADO). With the introduction of .NET, Microsoft created a new way to work with data,
called ADO.NET.

ADO.NET is a set of classes exposing data access services to .NET programmers, providing a rich
set of components for creating distributed, data-sharing applications. ADO.NET is an integral part
of the .NET Framework and provides access to relational, XML, and application data. ADO.NET
classes are found in System.Data.dll.

ADO.NET offers two types of architectural components to build data-centric applications:


connected and disconnected. Within Microsoft .NET Framework, ADO.NET is housed in the
namespace System.Data (the assembly name is System.Data.dll), so all the classes and functions
for connected and disconnected components live in the same namespace. Hence, it is important to
add a reference of System.Data to your application irrespective
Figure 1 ADD.NET architecture

Connected Data Objects

ADO.NET’s connected architecture relies on a consistent database connection to access data and
perform any operations on the retrieved data. ADO.NET offers the following objects to help you
build your application with a connected architecture:
 Connection: This is the main, or core, object for any database-oriented application. As
you might imagine, without knowing a data source’s statistics such as where it is located,
what database you would like to connect with, what user name and password it requires,
and so on, it would be impossible to establish a connection and perform any data-related
activity. Each .NET provider provides its own Connection object that offers features
targeted to specific data sources.
 Command: This object represents the handling of statements that your application will
be using to perform data-oriented tasks, such as reading data or inserting or modifying
data. Hence, any SQL statement is actually executed via a Command object.
 DataReader: DataReader involves creating an instance of the Command object and then
creating a DataReader by calling Command.ExecuteReader for data retrieval from your
data source, the returned data can be fetched in a read-only way through a DataReader
object. Data retrieval behavior of DataReader is also known as a read-forward-only fire-
hose cursor with fast speed.
 Parameter: Parameter has always been an important part of any programming model.
Similarly, it is important in ADO.NET programming when it comes to passing values to
Command. A Parameter can be a value passed or returned to/from a stored procedure or
an argument passed to a SQL query.
 DataAdapter: DataAdapter is the object ADO.NET exposes to bridge the gap between
connected and disconnected architectures to let applications establish a connection and
sync data into and from the data source.

Disconnected Data Objects


ADO.NET’s connected architecture relies on a consistent database connection to access data
and perform any operations on the retrieved data. However, in today’s complex distributed
application environments, it is not possible to rely on a dedicated database connection to
retrieve and modify data.
To help you meet your business requirements and work with ease in your distributed
environment, you can utilize ADO.NET’s disconnected architecture; it offers flexible
application design and helps organizations save database connections. Hence, data can be
retrieved and then stored locally on the device in the form of a DataSet object. The retrieved
DataSet can be modified by users on their local devices such as laptops, handhelds, tablets,
and so on, and once that’s done, they can sync the changes into the central data source.
Disconnected architecture utilizes expansive resources like Connection in a very optimum way
(that is, to open late and close early). ADO.NET offers the following objects to help you build
your application with a disconnected architecture:
 DataSet: DataSet is the core architectural component of ADO.NET to make
disconnected applications. A data set can be considered a subset of data. A data set
supports disconnected, independent caching of data in a relational fashion, updating
the data source as required. A data set contains one or more data tables.
 DataTable: DataTable is a row-and-column representation that provides much the
same logical view as a physical table in a database. For example, you can store the
data from a database’s table in an ADO.NET DataTable and manipulate the data as
needed.
 DataRow: As you know, a table always consists of rows. In a similar manner,
ADO.NET’s DataTable consists of rows of the DataRowCollection type. This
DataRowCollection is an enumerable collection of DataRow objects. When new data
is added to the DataTable, a new DataRow is added.
 DataColumn: Just like any other column in a database table, ADO.NET’s DataTable
consists of a DataColumn of the DataColumnCollection type.
 DataView: DataView in ADO.NET serves a purpose similar to a view in a database.
Usually a view in a databse provides a predefined, organized, or filtered set of
records. Similarly, a DataView provides filtered or sorted records from a DataTable.
Just like a database table can have multiple views, so too can the DataTable have
multiple data views on it.

The .NET data providers


ADO.NET consists of various data providers that allow an easy and predefined object model
to communicate with various industry databases such as SQL Server, Oracle, Microsoft
Access, and many others.
There are various database providers, so each data provider has its own namespace. In fact,
each data provider is essentially an implementation of interfaces in the System.Data
namespace, specialized for a specific type of data source.
For example, if you use SQL Server, you should use the SQL Server data provider
(System.Data.SqlClient) because it’s the most efficient way to access SQL Server.
The OLE DB data provider supports access to older versions of SQL Server as well as to
other databases, such as Access, DB2, MySQL, and Oracle. However, native data providers
(such as System.Data.OracleClient) are preferable for performance, since the OLE DB data
provider works through two other layers, the OLE DB service component and the OLE DB
provider, before reaching the data source.

Figure 2 SQL Server and OLE DB data provider differences

If your application connects to an older version of SQL Server (6.5 or older) or to more than one kind of
database server at the same time (for example, an Access and an Oracle database connected
simultaneously), only then should you choose to use the OLE DB data provider.

No hard-and-fast rules exist; you can use both the OLE DB data provider for SQL Server and the Oracle
data provider (System.Data.OracleClient) if you want, but it’s important you choose the best provider
for your purpose. Given the performance benefits of the server-specific data providers, if you use SQL
Server, 99 percent of the time you should be using the System.Data.SqlClient classes.

Before we look at what each kind of data provider does and how it’s used, you need to be clear on their
core functionality. Each .NET data provider is designed to do the following two things very well:

 Provide access to data with an active connection to the data source


 Provide data transmission to and from disconnected data sets and data tables.

Database connections are established by using the data provider’s Connection class (for example,
System.Data.SqlClient.SqlConnection). Other components such as data readers, commands, and data
adapters support retrieving data, executing SQL statements, and reading or writing to data sets or data
tables, respectively.
As you’ve seen, each data provider is prefixed with the type of data source it connects to (for instance,
the SQL Server data provider is prefixed with Sql), so its connection class is named SqlConnection. The
OLE DB data provider’s connection class is named OleDbConnection. Let’s understand the three data
providers that can be used with SQL Server.

Most commonly used data providers are: -

 SQL Server Data Provider


 OLEDB data provider and
 ODBC data provider

SQL Server Data Provider


The .NET data provider for SQL Server is in the System.Data.SqlClient namespace. Although you can use
System.Data.OleDb to connect with SQL Server, Microsoft has specifically designed the
System.Data.SqlClient namespace to be used with SQL Server, and it works in a more efficient and
optimized way than System.Data.OleDb. The reason for this efficiency and optimized approach is that
this data provider communicates directly with the server using its native network protocol instead of
through multiple layers.
Table 1 Commonly used SQL Server Data provider Classes

Classes Description

SqlCommand Executes SQL queries, statements, or stored


procedures
SqlConnection Represents a connection to a SQL Server
database
SqlDataAdapter Represents a bridge between a data set and a
data source
SqlDataReader Provides a forward-only, read-only data
stream of the results
SqlError Holds information on SQL Server errors and
warnings
SqlException Defines the exception thrown on a SQL
Server error or warning
SqlParameter Represents a command parameter
SqlTransaction Represents a SQL Server transaction

OLE DB Data Provider


Outside .NET, OLE DB is still Microsoft’s high-performance data access technology. The
OLE DB data provider has been around for many years. If you’ve programmed for Microsoft
Access in the past, you may recall using Microsoft Jet OleDb 3.5 or 4.0 to connect with the
Microsoft Access database. You can use this data provider to access data stored in any
format, so even in ADO.NET it plays an important role in accessing data sources that don’t
have their own ADO.NET data providers.
Table 2 commonly used OLE DB Data Provider Classes

Classes Description

OleDbCommand Executes SQL queries, statements, or stored


procedures
OleDbConnection Represents a connection to a OleDb data
source
OleDbDataAdapter Represents a bridge between a data set and a
data source
OleDbDataReader Provides a forward-only, read-only data
stream of rows from a data source
OleDbError Holds information on errors and warnings
returned by the data source
OleDbParameter Represents a command parameter
OleDbTransaction Represents a SQL transaction

Notice the similarity between the two data providers SqlClient and OleDb. The differences in
their implementations are transparent, and the user interface is fundamentally the same. The
ADO.NET OLE DB data provider requires that an OLE DB provider be specified in the
connection string.
Table 3 describes some OLE DB providers.

Provider Description
DB2OLEDB Microsoft OLE DB provider for DB2
SQLOLEDB Microsoft OLE DB provider for SQL Server
MicrosoftJet.OLEDB.4.0 Microsoft OLE DB provider for Access
(which uses the Jet engine)
MSDAORA Microsoft OLE DB provider for Oracle
MSDASQL Microsoft OLE DB provider for ODBC

ODBC Data Provider


ODBC was Microsoft’s original general-purpose data access technology. It’s still widely
used for data sources that don’t have OLE DB providers or .NET Framework data providers.
ADO.NET includes an ODBC data provider in the namespace System.Data.Odbc.
The ODBC architecture is essentially a three-tier process. An application uses ODBC
functions to submit database requests. ODBC converts the function calls to the protocol
(call-level interface) of a driver specific to a given data source. The driver communicates
with the data source, passing any results or errors back to ODBC. Obviously, this is less
efficient than a database-specific data provider’s direct communication with a database, so
for performance it’s preferable to avoid the ODBC data provider, since it merely offers a
simpler interface to ODBC but still involves all the ODBC overhead. Table 10-5 describes
some important classes in the Odbc namespace.
Table 4 Commonly Used Odbc Classes

Classes Description
Executes SQL queries, statements, or stored
OdbcCommand procedures
OdbcConnection Represents a connection to an ODBC data
source
OdbcDataAdapter Represents a bridge between a data set and a
data source
OdbcDataReader Provides a forward-only, read-only data
stream of rows from a data source
OdbcError Holds information on errors and warnings
returned by the data source
OdbcParameter Represents a command parameter
OdbcTransaction Represents a SQL transaction

LINQ Architecture
LINQ is an innovation that Microsoft made with the release of Visual Studio 2008 and .NET
Framework version 3.5 that promises to revolutionize the way developers work with data.
Microsoft has continued to improve LINQ with the recent releases of .NET 4.0/4.5 and Visual
Studio 2012. As mentioned, LINQ allows you to query various types of data sources including
relational databases, XML documents, and even in-memory data structures. LINQ supports all
these types of data stores with the help of LINQ query expressions of first-class language
constructs in C# 2012. LINQ offers the following advantages:
• LINQ offers common syntax for querying any type of data source; for example, you can
query an XML document in the same way you query a SQL database, an ADO.NET
dataset, an in-memory collection, or any other remote or local data source that you have
chosen to connect to and access by using LINQ.
• LINQ bridges the gap and strengthens the connection between relational data and the
object-oriented world.
• LINQ speeds development time by catching many errors at compile time and including
IntelliSense and debugging support.
• LINQ query expressions (unlike traditional SQL statements) are strongly typed.
LINQ consists of three major components:
• LINQ to Objects •
• LINQ to ADO.NET, which includes
o LINQ to SQL (formerly called DLinq)
o LINQ to DataSets (formerly called LINQ over DataSets)
o LINQ to Entities
• LINQ to XML (formerly called XLinq)
Table 5 LINQ Architecture

Reference

[1] V. V. Agarwal, Begining C# 5.0 Databases, second Edition ed., apress.


The following shows creating a simple desktop application; design an application, creating and
connecting a database for designed application, create classes and methods for each entities. by
the end get the value from the input fields.

This figure shows the designing part of an application

The following code describes that creating class and methods for the application.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Econtact.econtactClass
{
internal class contactClass
{
//geter setter properties
//Acts as data carreir in our application

public int ContactID { get; set; }


public string FirstName { get; set; }
public string LastName { get; set; }
public string ContactNo { get; set; }
public string Address { get; set; }
public string Gender { get; set; }

static string myconnstrng =


ConfigurationManager.ConnectionStrings["connstrng"].ConnectionString;

//selecting data from database

public DataTable select()


//step 1: Database connection
{
SqlConnection conn = new SqlConnection(myconnstrng);
DataTable dt = new DataTable();
try
{
//writing SQL Query
string sql = "SELECT*FROM tbl_contact";
//creaating cmd using sql and conn

SqlCommand cmd = new SqlCommand(sql, conn);


//creating sql dataAdapter using cmd
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
conn.Open();
adapter.Fill(dt);

}
catch(Exception ex)
{

}
finally
{
conn.Close();
}
return dt;
}
//Inserting data into database

public bool Insert (contactClass c)


{
//creating a default return type and setting its value to false
bool isSuccess = false;

// step 1: connect Database


SqlConnection conn = new SqlConnection(myconnstrng);
try
{
// create sql Query to insert data

string sql = "INSERT INTO tbl_contact (FirstName, LastName,


ContactNo, Address, Gender) VALUES (@FirstName, @LastName, @ContactNo, @Address,
@Gender)";
//creating sql command using sql and conn
SqlCommand cmd = new SqlCommand(sql, conn);

//create parameters to add data


cmd.Parameters.AddWithValue("FirstName", c.FirstName);
cmd.Parameters.AddWithValue("@LastName", c.LastName);
cmd.Parameters.AddWithValue("@ContactNo", c.ContactNo);
cmd.Parameters.AddWithValue("@Address", c.Address);
cmd.Parameters.AddWithValue("@Gender", c.Gender);
// connection open here
conn.Open();
int rows = cmd.ExecuteNonQuery();
//if the query runs successfully then the value of rows will be
greater than zero else its value will be 0
if(rows>0)
{
isSuccess = true;
}
else
{
isSuccess = false;
}
}
catch (Exception ex)
{

}
finally
{
conn.Close();
}
return isSuccess;
}
// Method to Update Data
public bool Update(contactClass c)
{
//create a default return type and set its default value fale
bool isSuccess = false;
SqlConnection conn = new SqlConnection(myconnstrng);
try
{
//sql to update data in database
string sql = "UPDATE tbl_contact SET FirstName=@FirstName,
LastName=@LastName, ContactNo=@ContactNo, Address=@Address, Gender=@Gender WHERE
ContactID=@ContactID";
//creating sql command
SqlCommand cmd = new SqlCommand(sql, conn);
//create prameters to add values
cmd.Parameters.AddWithValue("@FirstName", c.FirstName);
cmd.Parameters.AddWithValue("@LastName", c.LastName);
cmd.Parameters.AddWithValue("@ContactNo", c.ContactNo);
cmd.Parameters.AddWithValue("@Address", c.Address);
cmd.Parameters.AddWithValue("@Gender", c.Gender);
cmd.Parameters.AddWithValue("@ContactID", c.ContactID);
//open database connection
conn.Open();
int rows = cmd.ExecuteNonQuery();
//if the query runs successfully then the value of rows will be
greater than zero else its value is 0
if(rows>0)
{
isSuccess = true;
}
else
{
isSuccess = false;
}
}
catch(Exception ex)
{

}
finally
{
conn.Close();
}
return isSuccess;
}
//Method to Delete Data from Databasae

public bool Delete(contactClass c)


{
//create a default return value and set its value false
bool isSuccess = false;
//create sql connection
SqlConnection conn = new SqlConnection(myconnstrng);
try
{
//sql to delete data
string sql = "DELETE FROM tbl_contact WHERE ContactID=@ContactID";
//creating sql command
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@ContactID", c.ContactID);
//oppen connection
conn.Open();
int rows = cmd.ExecuteNonQuery();
//if the query run successfully then the value of rows greater than
zero else its value is 0
if(rows>0)
{
isSuccess = true;
}
else
{
isSuccess = false;
}
}
catch(Exception ex)
{

}
finally
{
//connection close
conn.Close();
}
return isSuccess;
}
}
}
The following code identifies how to get the value from the input fields and how to load the data
from the application through database.
using Econtact.econtactClass;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Econtact
{
public partial class Econtact : Form
{
public Econtact()
{
InitializeComponent();
}
contactClass c = new contactClass();

private void Econtact_Load(object sender, EventArgs e)


{
//load data on Data Gridview
DataTable dt = c.select();
dgvContactlist.DataSource = dt;
}

private void btnAdd_Click(object sender, EventArgs e)


{
//Get the value from the input fields
c.FirstName = txtBoxFirstName.Text;
c.LastName = txtBoxLastName.Text;
c.ContactNo = txtBoxContactNo.Text;
c.Address = txtBoxAddress.Text;
c.Gender = cmbGender.Text;
//inserting data into database using the method wwe created in the
previous
bool success = c.Insert(c);
if(success==true)
{
//sucessfully inserted

MessageBox.Show("New Contact Successfully Inserted");


//call the Clear method here
Clear();
}
else
{
//failed to add new contact
MessageBox.Show("Failed to Add new contact. Try again");
}
//load data on Data Gridview
DataTable dt = c.select();
dgvContactlist.DataSource = dt;
}
//method to Clear fields
public void Clear()
{
txtBoxFirstName.Text = "";
txtBoxLastName.Text = "";
txtBoxContactNo.Text = "";
txtBoxAddress.Text = "";
cmbGender.Text = "";
}

private void btnUpdate_Click(object sender, EventArgs e)


{
//Get the data from text boxes to Update the data
c.ContactID=int.Parse(txtBoxContactID.Text);
c.FirstName = txtBoxFirstName.Text;
c.LastName = txtBoxLastName.Text;
c.ContactNo= txtBoxContactNo.Text;
c.Address = txtBoxAddress.Text;
c.Gender = cmbGender.Text;
//Update data in Database
bool success= c.Update(c);
if(success==true)
{
//Update Successfully
MessageBox.Show("Contact has been successfully Updated.");
//load data on Data Gridview
DataTable dt = c.select();
dgvContactlist.DataSource = dt;
//call clear method
Clear();
}
else
{
//failed to Update
MessageBox.Show("Failed to Update Contact");
}
}

private void dgvContactlist_RowHeaderMouseClick(object sender,


DataGridViewCellMouseEventArgs e)
{
//Get the data from Data Grid View and load it to the text boxes
respectively
//identify the row on which mouse is click
int rowIndex=e.RowIndex;
txtBoxContactID.Text =
dgvContactlist.Rows[rowIndex].Cells[0].Value.ToString();
txtBoxFirstName.Text =
dgvContactlist.Rows[rowIndex].Cells[1].Value.ToString();
txtBoxLastName.Text =
dgvContactlist.Rows[rowIndex].Cells[2].Value.ToString();
txtBoxContactNo.Text =
dgvContactlist.Rows[rowIndex].Cells[3].Value.ToString();
txtBoxAddress.Text =
dgvContactlist.Rows[rowIndex].Cells[4].Value.ToString();
cmbGender.Text =
dgvContactlist.Rows[rowIndex].Cells[5].Value.ToString();
}

private void btnClear_Click(object sender, EventArgs e)


{
//call clear method here
Clear();
}

private void btnDelete_Click(object sender, EventArgs e)


{
//Get Contact ID from Application
c.ContactID=Convert.ToInt32(txtBoxContactID.Text);
bool success = c.Delete(c);
if(success==true)
{
//Successfully Deleted
MessageBox.Show("Contact Successfully Deleted.");
//Refresh Data Grid View
//load data on Data Gridview
DataTable dt = c.select();
dgvContactlist.DataSource = dt;
//call clear method, to clear the data automatically after
successfully deleted
Clear();
}
else
{
//Failed to Delete
MessageBox.Show("Failed to Delete Contact. Try Again");
}
}
static string myconnstrng =
ConfigurationManager.ConnectionStrings["connstrng"].ConnectionString;
private void txtBoxSearch_TextChanged(object sender, EventArgs e)
{
//Get the value from text box
string keyword=txtBoxSearch.Text;
SqlConnection conn=new SqlConnection(myconnstrng);
SqlDataAdapter sda = new SqlDataAdapter("SELECT * FROM tbl_contact WHERE
FirstName LIKE '%"+keyword+"%' OR LastName LIKE '%"+keyword+"%' OR Address LIKE
'%"+keyword+"%'",conn);
DataTable dt=new DataTable();
sda.Fill(dt);
dgvContactlist.DataSource = dt;
}
}
}

You might also like