Anda di halaman 1dari 66

ADO .NET What is ADO.Net?

Most of the todays applications need to interact with database systems to persist, edit or view data. In .Net data access service is provided through ADO.Net (ActiveX Data Object in Dot Net) components. ADO.Net is an object oriented framework that allows you to interact with database systems. We usually interact with database systems through SQL queries or stored procedures. ADO.Net encapsulates our queries and commands to provide a uniform access to various database management systems.

ADO.Net is a successor of ADO (ActiveX Data Object). The prime features of ADO.Net are its disconnected data access architecture and XML integration.

What does it mean by disconnected data access architecture of ADO.Net?


ADO.Net introduces the concept of disconnected data architecture. In traditional data access components, you make a connection to the database system and then interact with it through SQL queries using the connection. The application stays connected to the DB system even when it is not using DB services. This commonly wastes the valuable and expensive database resource as most of the time applications only query and view the persistent data. ADO.Net solves this problem by managing a local buffer of persistent data called data set. Your application automatically connects to the database server when it needs to pass some query and then disconnects immediately after getting the result back and storing it in dataset. This design of ADO.Net is called disconnected data architecture and is very much similar to the connection less services of http over the internet. It should be noted that ADO.Net also provides the connection oriented traditional data access services.

Traditional Data Access Architecture

ADO.Net Disconnected Data Access Architecture

Another important aspect of the disconnected architecture is that it maintains the local repository of data in the dataset object. The dataset object stores the tables, their relationship and different constraints. The user performs operations like update, insert, delete to this dataset locally and finally the changed dataset is stored in actual database as a batch when needed. This greatly reduces the network traffic and results in the better performance.

What does it mean by connected data access architecture of ADO.Net?


In the connected environment, it is your responsibility to open and close the database connection. You first establish the database connection, perform the interested operations to the database and when you are done, close the database connection. All the changes are done directly to the database and no local (memory) buffer is maintained.

What's the difference between accessing data with dataset or data reader?
The dataset is generally used when you like to employ the disconnected architecture of the ADO.Net. It reads the data into the local memory buffer and perform the data operations (update, insert, delete) locally to this buffer. The data reader, on the other hand, is directly connected to the database management system. It passes all the queries to the database management system, which executes them and returns the result back to the application. Since no memory buffer is maintained by the data reader, it takes up fewer resources and performs more efficiently with small number of data operations. The dataset, on the other hand is more efficient when large number of updates are to be made to the database. All the updates are done in the local memory and are updated to the database in a batch. Since database connection remains open for the short time, the database management system does not get flooded with the incoming requests.

What are the performance considerations when using dataset?


Since no memory buffer is maintained by the data reader, it takes up fewer resources and performs more efficiently with small number of data operations. The dataset, on the other hand is more efficient when large number of updates are to be made to the database. All the updates are done in the local memory and are updated to the database in a batch. Since database connection remains open for the short time, the database management system does not get flooded with the incoming requests. However, since the dataset stores the records in the local buffer in the hierarchical form, it does take up more resources and may affect the overall performance of the application.

How to select dataset or data reader?


The data reader is more useful when you need to work with large number of tables, database in nonuniform pattern and you need not execute the large no. of queries on few particular table. When you need to work on fewer no. of tables and most of the time you need to execute queries on these fewer tables, you should go for the dataset. It also depends on the nature of application. If multiple users are using the database and the database needs to be updated every time, you must not use the dataset. For this, .Net provides the connection oriented architecture. But in the scenarios where instant update of database is not required, dataset provides optimal performance by making the changes locally and connecting to database later to update a whole batch of data. This also reduces the network bandwidth if the database is accessed through network. Disconnected data access is suited most to read only services. On the down side, disconnected data access architecture is not designed to be used in the networked environment where multiple users are updating data simultaneously and each of them needs to be aware of current state of database at any time (e.g., Airline Reservation System).

How XML is supported in ADO.Net?


The dataset is represented in the memory as an XML document. You can fill the dataset by XML and can also get the result in the form of XML. Since XML is an international and widely accepted standard, you can read the data using the ADO.Net in the XML form and pass it to other applications using Web Service. These data consuming application need not be the essentially Dot Net based. They may be written with Java, C++ or any other programming language and running on any platform.

What are the different components of ADO.Net?


The famous diagram of the ADO.Net architecture and its components is presented in the figure below:

All generic classes for data access are contained in the System.Data namespace. A short description of the core classes of ADO.Net is presented below:

Class DataSet DataTable

Description The DataSet is a local buffer of tables or a collection of disconnected record sets DataTable is used to contain the data in tabular form using rows and columns. DataRow Represents a single record or row in DataTable

DataRow Represents a single record or row in DataTable DataColu Represents a column or field of DataTable mn DataRelati Represents the relationship between different tables in a data set. on Constraint Represents the constraints or limitations that apply to a particular field or column.
ADO.Net also contains some database specific classes. This means that different database system providers may provide classes (or drivers) optimized for their particular database system. The provider for such classes is called the Dot Net Framework Data Providers. Microsoft itself has provided the specialized and optimized classes for their SQL server database system. The name of these classes start with Sql and these are contained in System.Data.SqlClient namespace. Similarly, Oracle has also provided its classes (driver) optimized for Oracle DB System. Microsoft has also provided the general classes which can connect your application to any OLE supported database server. The name of these classes start with OleDb and these are contained in System.Data.OleDb namespace. In fact, you can use OleDb classes to connect to SQL server or Oracle database but using the database specific classes generally provides optimized performance. The core objects that make up a data provider are:

Class

Description

Connectio Represents a connection to the database system n Command Represents SQL query or command to be executed at the database management system

A class that connects to the database system fetches the record and fills the dataset. It DataAdap contains four different commands to perform database operations; Select, Update, ter Insert, Delete. DataRead A stream that reads data from the database in connected design er Parameter Represents a parameter to a stored procedure

What is a dataset?
A dataset is the local repository of the data used to store the tables and disconnected record set. When using disconnected architecture, all the updates are made locally to dataset and then the updates are performed to the database as a batch.

What is a data adapter?


A data adapter is the component that exists between the local repository (dataset) and the physical database. It contains the four different commands (SELECT, INSERT, UPDATE and DELETE). It uses these commands to fetch the data from the DB and fill into the dataset and to perform updates done in the dataset to the physical database. It is the data adapter that is responsible for opening and closing the database connection and communicates with the dataset.

What is a database connection?


A database connection represents a communication channel between you application and database management system (DBMS). The application uses this connection to pass the commands and queries to the database and obtain the results of the operations from the database.

What is a database command?


A database command specifies which particular action you want to perform to the database. The commands are in the form of SQL (Structured Query Language). There are four basic SQL statements that can be passed to the database.

SQL SELECT Statement


This query is used to select certain columns of certain records from a database table.
SELECT * from emp

Selects all the fields of all the records from the table name emp
SELECT empno, ename from emp

Selects the fields empno and ename of all records from the table name emp
SELECT * from emp where empno < 100

Selects all those records from the table name emp that have the value of the field empno less than 100
SELECT * from article, author where article.authorId = author.authorId

selects all those records from the table name article and author that have same value of the field authorId

SQL INSERT Statement


This query is used to insert a record to a database table.
INSERT INTO emp (empno, ename) values (101, John Guttag)

Inserts a record to emp table and set its empno field to 101 and its ename field to John Guttag

SQL UPDATE Statement


This query is used to edit an already existing record in a database table.
UPDATE emp SET ename =Eric Gamma WHERE empno = 101

Updates the record whose empno field is 101 by setting its ename field to Eric Gamma

SQL DELETE Statement


This query is used to delete the existing record(s) from the database table
DELETE FROM emp WHERE empno = 101

Deletes the record whose empno field is 101 from the emp table

What is a data reader?


The data reader is a component that reads the data from the database management system and provides it to the application. The data reader works in the connected manner; it reads a record from the DB, pass it to the application, then reads another and so on.

How do different components of ADO.Net interact with each other in disconnected architecture?
The Data Adapter contains in it the Command and Connection object. It uses the connection object to connect to the database, execute the containing command, fetch the result and update the DataSet.

How do different components of ADO.Net interact with each other in connected architecture?
Here, the Command object contains the Connection object. The Command object uses the containing connection (that must be opened) to execute the SQL query and if the SQL statement is SELECT, returns

the DataReader object. The data reader object is the stream to the database which reads the resulting records from the DB and passes them to the application

What does it mean by Dot Net Framework Data Provider?


Dot Net Framework Data Provider is a set of classes that establishes the database communication between an application and the database management system based on the standards of ADO.Net framework. Different data providers provide specialized and optimized connectivity to particular database management system or to a particular class of DBMS. For example, the MS SQL Server data provider provides the optimized connectivity between dot net application and MS SQL Server DBMS while the OLEDB data provider provides the uniform connectivity between dot net application and the OLEDB databases.

What are the core objects that make up a dot net framework data provider?
The core objects that make up a data provider are:

Class

Description

Connectio Represents a connection to the database system n Command Represents SQL query or command to be executed at the database management system

A class that connects to the database system, fetch the record and fill the dataset. It DataAdap contains four different commands to perform database operations; Select, Update, ter Insert, Delete. DataRead A stream that reads data from the database in connected design er Parameter Represents a parameter to a stored procedure

What are the standard dot net framework data providers that are shipped with the Dot Net Framework 1.1?
The Dot Net Framework 1.1 is shipped with four different data providers:

Dot Net Framework data provider for Microsoft SQL Server DBMS Dot Net Framework data provider for Oracle DBMS (available only in Framework 1.1) Dot Net Framework data provider for OLEDB supporting DBMS Dot Net Framework data provider for ODBC supporting data sources (available only in Framework 1.1)

Why should one use a specialized data provider when the data can be accessed with general data providers?
The specialized data providers (e.g., SQL Server and Oracle) are built specially for a particular kind of DBMS and works much more efficiently than the general data providers (e.g., OLEDB and ODBC). In practice, the specialized data providers are many times efficient than the general data providers.

What is the Dot Net Framework data provider for SQL Server?
The dot net framework data provider for SQL Server is the optimized data provider for Microsoft SQL Server 7 or later. It is recommended to use SQL Server data provider to access the SQL Server DB than general provider like OLEDB. The classes for this provider are present in the System.Data.SqlClient namespace.

What is the Dot Net Framework data provider for Oracle?


The dot net framework data provider for Oracle is the optimized data provider for Oracle DBMS. It is recommended to use Oracle data provider to access the Oracle DB than general provider like OLEDB. It supports the Oracle Client version 8.1.7 and later. The classes for this provider are present in the System.Data.OracleClient namespace. This provider is included in the .Net framework 1.1 and was not available in the Dot Net framework 1.0.

What is the Dot Net Framework data provider for OLEDB?


The dot net framework data provider for OLEDB provides connectivity with the OLEDB supported database management systems. It is the recommended middle tier for the SQL Server 6.5 or earlier and Microsoft Access Database. It is a general data provider. You can also use it to connect with the SQL Server or Oracle Database Management Systems. The classes for this provider are present in the System.Data.OleDBClient namespace.

What is the Dot Net Framework data provider for ODBC?


The dot net framework data provider for ODBC provides connectivity with the ODBC supported database management systems and data sources. It is a general data provider. You can also use it to connect with the SQL Server or Oracle Database Management Systems. The classes for this provider are present in the System.Data.ODBCClient namespace. This provider is included in the .Net framework 1.1 and was not available in the Dot Net framework 1.0.

What are the basic steps involved in data access with ADO.Net in disconnected environment?
Data access using ADO.Net involves the following steps: Defining the connection string for the database server

Defining the connection (SqlConnection, OleDbConnection, etc) to the database using the connection string Defining the command (SqlCommand, OleDbCommand, etc) or command string that contains the query Defining the data adapter (SqlDataAdapter, OleDbDataAdapter, etc) using the command string and the connection object Creating a new DataSet object If the command is SELECT, filling the dataset object with the result of the query through the data adapter Reading the records from the DataTables in the datasets using the DataRow and DataColumn objects If the command is UPDATE, INSERT or DELETE, then updating the dataset through the data adapter Accepting to save the changes in the dataset to the database

Which namespaces I need to add to my project for each of the standard data provider?
You need to add following namespaces for the specified data providers:

Data Provider Namespace MS SQL Server Oracle Database OLE Databases ODBC Sources System.Data.SqlClie nt System.Data.OracleC lient DBSystem.Data.OleDBC lient DataSystem.Data.ODBCCl ient

How do I define a connection string for the database server?


For MS SQL Server, used with the SQL Server data provider, we can write the connection string like:

C# Version
// for Sql Server string connectionString = "server=P-III; database=programmersheaven;" +_ "uid=sa; pwd=;";

VB.Net Version
' for Sql Server Dim connectionString As String = "server=P-III; database=programmersheaven;" + _ "uid=sa; pwd=;"

First of all we have defined the instance name of the server, which is P-III on my system. Next we defined the name of the database, user id (uid) and password (pwd). Since my SQL server doesn't have a password for the System Administrator (sa) user, I have left it blank in the connection string. (Yes I know this is very dangerous and is really a bad practice - never, ever use a blank password on a system that is accessible over a network) For Oracle Database Server, used with the Oracle data provider, we can write the connection string like:

C# Version
string connectionString = "Data Source=Oracle8i;User Id=username;" + "Password=pwd; Integrated Security=no;";

VB.Net Version
Dim connectionString As String = "Data Source=Oracle8i;User Id=username;" + _ "Password=pwd; Integrated Security=no;"

For MS Access Database, used with the OLE DB data provider, we can write the connection string like:

C# Version
// for MS Access string connectionString = "provider=Microsoft.Jet.OLEDB.4.0;" + "data source = c:\\programmersheaven.mdb";

VB.Net Version
' for MS Access Dim connectionString As String = "provider=Microsoft.Jet.OLEDB.4.0;" + _ "data source = c:\programmersheaven.mdb"

First we have defined the provider of the access database. Then we have defined the data source which is the address of the target database. For MS SQL Server, used with the ODBC data provider, we can write the connection string like:

C# Version
string connectionString = "Driver={SQL Server};Server=FARAZ;Database=pubs;Uid=sa;Pwd=;";

VB.Net Version
Dim connectionString As String = "Driver={SQL Server};Server=FARAZ;Database=pubs;Uid=sa;Pwd=;"

How do I find the connection string for the database server?


Usually the connection string options are provided in the documentation, you can also find the connection strings on the internet. A good website for the connections strings is http://www.connectionstrings.com

How do I define the connection to database?


A connection is defined using the connection string. The Connection object is used by the data adapter or data reader to connect to and disconnect from the database. For SQL Server used with SQL Server data provider, the connection is created like this:

C# Version
SqlConnection conn = new SqlConnection(connectionString);

VB.Net Version
Dim conn As New SqlConnection(connectionString)

For Oracle Database Server used with Oracle data provider, the connection is created like this:

C# Version
OracleConnection conn = new OracleConnection(connectionString);

VB.Net Version
Dim conn As New OracleConnection(connectionString)

For OLE DB provider, the connection is created like this:

C# Version
OleDbConnection conn = new OleDbConnection(connectionString);

VB.Net Version
Dim conn As New OleDbConnection(connectionString)

For ODBC data provider, the connection is created like this:

C# Version
OdbcConnection conn = new OdbcConnection(connectionString);

VB.Net Version
Dim conn As New OdbcConnection(connectionString)

Here we have passed the connection string to the constructor of the connection object.

How do I create a command and supply the SQL query to ADO.Net? (Command object and command string)
First of all, you create a command object (SqlCommand, OracleCommand, OleDbCommand, OdbcCommand) using the connection object (SqlConnection, OracleConnection, OleDbConnection, OdbcConnection) and set its CommandText property to the SQL query to execute.

C# Version
OdbcCommand cmd = conn.CreateCommand(); cmd.CommandText = "select * from authors";

VB.Net Version
Dim cmd As OdbcCommand cmd = conn.CreateCommand() cmd.CommandText = "select * from authors"

How do I define a data adapter?


The data adapter stores your command (query) and connection and using these connect to the database when asked, fetch the result of query and store it in the local dataset.

The DataAdapter class (SqlDataAdapter, OracleDataAdapter, OleDbDataAdapter, OdbcDataAdapter) may be instantiated in three ways: 1. by supplying the command string (SQL Select command) and connection string 2. by supplying the command string (SQL Select command) and a connection object 3. by supplying the command object (SqlCommand, OracleCommand, OleDbCommand, OdbcCommand) 4. For example, with SQL Server, the data adapter is created as

C# Version
// for Sql Server SqlDataAdapter dataAdapter = new SqlDataAdapter(commandString, conn);

VB.Net Version
Dim da As New SqlDataAdapter(commandString, conn)

Here we have created a new instance of data adapter and supplied it command string and connection object in the constructor call. For Access, the data adapter is created like

C# Version
// for MS Access OleDbDataAdapter dataAdapter = new OleDbDataAdapter(commandString, connectionString);

VB.Net Version
Dim da As New OleDbDataAdapter(commandString, connectionString)

Here we have created a new instance of data adapter and supplied it command string and connection string in the constructor call.

How do I get the result of my command and fill it to the dataset?


DataSet is a local and offline container of the data. The DataSet object is created simply like

C# Version
DataSet ds = new DataSet();

VB.Net Version
Dim ds As New DataSet()

Now we need to fill the DataSet with the result of the query. We will use the dataAdapter object for this purpose and call its Fill() method. This is the step where data adapter connects to the physical database and fetch the result of the query.

C# Version
dataAdapter.Fill(ds, "prog");

VB.Net Version
da.Fill(ds, "prog")

Here we have called the Fill() method of dataAdapter object. We have supplied it the dataset to fill and the name of the table (DataTable) in which the result of query is filled. This is all we needed to connect and fetch the data from the database. Now the result of query is stored in the dataset object in the prog table which is an instance of DataTable. We can get a reference to this table by using the indexer property of dataset objects Tables collection

C# Version
DataTable dataTable = ds.Tables["prog"];

VB.Net Version
Dim dataTable As DataTable dt = ds.Tables("prog")

The indexer we have used takes the name of the table in dataset and returns the corresponding DataTable object. Now we can use the tables Rows and Columns collection to access the data in the table.

How do I read records from the data tables?


You can read the records from the data table using its Rows collection. With the Rows collection, you need to specify the row number and column name or number to access a particular field of the specified row. For example, if we have read the Student table in our data table, we can access its individual fields as:

C# Version
DataTable dt = ds.Tables["student"]; string stId = dt.Rows[0]["StudentID"].ToString(); string stName = dt.Rows[0]["StudentName"].ToString(); string stDateOfBirth = dt.Rows[0][2].ToString();

VB.Net Version
Dim dt As DataTable dt = ds.Tables("student")

Dim stId As String stId = dt.Rows(0)("StudentID").ToString() Dim stName As String stName = dt.Rows(0)("StudentName").ToString() Dim stDateOfBirth As String stDateOfBirth = dt.Rows(0)(2).ToString()

Here we have retrieved various fields of the first record of the student table read in the dataset. As you can see, we can either specify the column name in string format or we can specify the column number in

integer format. Also note that the field value is returned in the form of Object, so we need to convert it to the string before using it. Similarly, you need to cast variables of other data types before using them.

C# Version
int stAge = int.Parse(dt.Rows(0)("Age").ToString());

VB.Net Version
Dim stage As Integer stAge = Integer.Parse(dt.Rows(0)("Age").ToString())

How do I save the changes, made in the dataset, to the database?


We update the dataset and table by calling the Update method of the data adapter. This saves the changes in the local repository of data: dataset. To save the changed rows and tables to the physical database, we call the AcceptChanges() method of the DataSet class.

C# Version
dataAdapter.Update(ds, "student"); ds.AcceptChanges();

VB.Net Version
da.Update(ds, "student") ds.AcceptChanges()

Here da is the reference to the data adapter object, ds is the reference to the dataset, and student is the name of table we want to update. Note: For the next four FAQs, we will demonstrate sample applications. For these applications to work, you need following database and tables created in your database server. A database named ProgrammersHeaven is created. It has a table named Article. The fields of the table Article are

Field Name artId Key) Title Topic

Type Description

(PrimaryInteg The unique identity of article er StringThe title of the article String Topic or Series name of the article like Multithreading in Java or C# School

authorId (ForeignInteg Unique identity of author Key) er Lines Integ No. of lines in the article er

dateOfPublishing Date Date of publishing of the article


The ProgrammersHeaven database also contains a table named Author with the following fields

Field Name

Type Description

authorId (PrimaryInteg The unique identity of Key) er author name StringName of author

How do I make my first Hello, ADO.Net Application in C#?


Lets now create a demonstration application for accessing data. First create a windows form application and make the layout like the following snapshot

We have set the Name property of the text boxes (from top to bottom) as txtArticleID, txtArticleTitle, txtArticleTopic, txtAuthorId, txtAuthorName, txtNumOfLines and txtDateOfPublishing. Also we have set the ReadOnly property of all the text boxes to true as dont want the user of application to change the text. The names of buttons (from top to bottom) are btnLoadTable, btnNext and btnPrevious. Initially we have disabled the Next and Previous buttons (by setting their Enabled property to false). We have also defined three variables in the Form class as
public class ADOForm : System.Windows.Forms.Form { DataTable dataTable; int currRec=0;

int totalRec=0;

The dataTable object will be used to reference the table returned as a result of the query. The currRec and totalRec integer variables are used to keep track of the current record and total records in the table.

Loading table
For LoadTable button, we have written the following event handler
private void btnLoadTable_Click(object sender, System.EventArgs e) { // for Sql Server string connectionString = "server=P-III; database=programmersheaven;" + "uid=sa; pwd=;";

// for MS Access /*string connectionString = "provider=Microsoft.Jet.OLEDB.4.0;" + "data source = c:\\programmersheaven.mdb";*/

// for Sql Server SqlConnection conn = new SqlConnection(connectionString);

// for MS Access //OleDbConnection conn = new OleDbConnection(connectionString);

string commandString = "SELECT " + "artId, title, topic, " + "article.authorId as authorId, " + "name, lines, dateOfPublishing " + "FROM " + "article, author " + "WHERE " + "author.authorId = article.authorId";

// for Sql Server SqlDataAdapter dataAdapter = new SqlDataAdapter(commandString, conn);

// for MS Access //OleDbDataAdapter dataAdapter = new OleDbDataAdapter(commandString, conn);

DataSet ds = new DataSet(); dataAdapter.Fill(ds, "prog");

dataTable = ds.Tables["prog"]; currRec = 0; totalRec = dataTable.Rows.Count;

FillControls();

btnNext.Enabled = true; btnPrevious.Enabled = true; }

In the start, we have created the connection, data adapter and filled the dataset object which we have discussed earlier. It should be noted that we have commented the code for OleDb provider (MS-Access) and are using the SQL Server specific code. If you like to use Access database, you can simply comment the SQL server code and de-comment the Access code. Next we assigned the data table resulted from query to the dataTable object which we declared at class level, assigned zero to currRec variable and assigned the number of rows in the dataTable to totalRec variable

dataTable = ds.Tables["prog"]; currRec = 0; totalRec = dataTable.Rows.Count;

Then we called the FillControls() method which fills the controls (text boxes) on the form with the current record of table prog. Finally we have enabled the Next and Previous Button

Filling the controls on the Form


The FillControls() method in our program fills the controls on the form with the current record of the data table. The method is defined as
private void FillControls() { txtArticleId.Text = dataTable.Rows[currRec]["artId"].ToString(); txtArticleTitle.Text = dataTable.Rows[currRec]["title"].ToString(); txtArticleTopic.Text = dataTable.Rows[currRec]["topic"].ToString(); txtAuthorId.Text = dataTable.Rows[currRec]["authorId"].ToString(); txtAuthorName.Text = dataTable.Rows[currRec]["name"].ToString(); txtNumOfLines.Text = dataTable.Rows[currRec]["lines"].ToString(); txtDateOfPublishing.Text = dataTable.Rows[currRec]["dateOfPublishing"].ToString(); }

Here we have set the Text property of the text boxes to the string values of the corresponding fields of current record. We have used the Rows collection of the dataTable and using its indexer we have got the DataRow representing the current record. We then accessed the indexer property of this DataRow using the column name to get the data in the respective field. If this explanation looks weird to you, you can simplify the above statements as

DataRow row = dataTable.Rows[currRec]; // getting current row object data = row["artId"]; // getting data in the artId field

string strData = data.ToString(); // converting to string txtArticleId.Text = strData; // display in the text box

which is equivalent to
txtArticleId.Text = dataTable.Rows[currRec]["artId"].ToString();

Hence when you start the application and press the LoadTable button, you will see the following output

How do I make my first Hello, ADO.Net Application in VB.Net?


Let's now create a demonstration application for accessing data. First create a windows form application and make the layout shown the following snapshot.

We have set the Name property of the text boxes (from top to bottom) as txtArticleID, txtArticleTitle, txtArticleTopic, txtAuthorId, txtAuthorName, txtNumOfLines and txtDateOfPublishing. Also we have set the

ReadOnly property of all the text boxes to true as don't want the user to change the text. The names of the buttons (from top to bottom) are btnLoadTable, btnNext and btnPrevious. Initially we have disabled the Next and Previous buttons (by setting their Enabled property to false). We have also defined three variables in the Form class:

Public Class ADOForm Inherits System.Windows.Forms.Form Private dataTable As dataTable Private currRec As Integer = 0 Private totalRec As Integer = 0 ... ' Private global members to be used in various methods

The dataTable object will be used to reference the table returned as a result of the query. The currRec and totalRec integer variables are used to keep track of the current record and total number of records in the table. Loading table For the LoadTable button, we have written the following event handler

Private Sub btnLoadTable_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadTable.Click ' for Sql Server Dim connectionString As String = "server=P-III; database=programmersheaven;" + _ "uid=sa; pwd=;"

' for MS Access 'Dim connectionString As String = "provider=Microsoft.Jet.OLEDB.4.0;" + ' "data source = c:\\programmersheaven.mdb"

' for Sql Server Dim conn As New SqlConnection(connectionString)

' for MS Access 'Dim conn As New OleDbConnection(connectionString)

Dim commandString As String = "SELECT " + _ "artId, title, topic, " + _

"article.authorId as authorId, " + _ "name, lines, dateOfPublishing " + _ "FROM " + _ "article, author " + _ "WHERE " + _ "author.authorId = article.authorId"

' for Sql Server Dim dataAdapter As New SqlDataAdapter(commandString, conn)

For MS Access 'Dim dataAdapter As New OleDbDataAdapter(commandString, conn)

Dim ds As New DataSet() dataAdapter.Fill(ds, "prog")

dataTable = ds.Tables("prog") currRec = 0 totalRec = dataTable.Rows.Count

FillControls()

btnNext.Enabled = True btnPrevious.Enabled = True

End Sub

First we created the connection, data adapter and filled the dataset object, all of which we have discussed earlier. It should be noted that we have commented out the code for the OleDb provider (MS-Access) and

are using SQL Server specific code. If you would like to use an Access databases, you can simply comment the SQL server code out and de-comment the Access code. Next, we have assigned the data table resulting from the query to the dataTable object which we declared at the class level, assigned zero to currRec variable and assigned the number of rows in the dataTable to the totalRec variable:
dataTable=ds.Tables("prog")currRec=0totalRec=dataTable.Rows.Count

Then we called the FillControls() method, which fills the controls (text boxes) on the form with the current record of the table "prog". Finally we enabled the Next and Previous Buttons.

Filling the controls on the Form


The FillControls() method in our program fills the controls on the form with the current record of the data table. The method is defined as follows:
Private Sub FillControls() txtArticleId.Text=dataTable.Rows(currRec)("artId").ToString() txtArticleTitle.Text=dataTable.Rows(currRec)("title").ToString() txtArticleTopic.Text=dataTable.Rows(currRec)("topic").ToString() txtAuthorId.Text=dataTable.Rows(currRec)("authorId").ToString() txtAuthorName.Text=dataTable.Rows(currRec)("name").ToString() txtNumOfLines.Text=dataTable.Rows(currRec)("lines").ToString() txtDateOfPublishing.Text=dataTable.Rows(currRec)("dateOfPublishing").ToString() End Sub

Here we have set the Text property of the text boxes to the string values of the corresponding fields of the current record. We have used the Rows collection of the dataTable and using its indexer we have got the DataRow representing the current record. We have then accessed the indexer property of this DataRow using the column name to get the data in the respective field. If this explanation looks weird to you, you can simplify the above statements to:Dim row As DataRow = dataTable.Rows(currRec) ' getting current row Dim data As Object = row("artId") Dim strData As String = data.ToString() txtArticleId.Text = strData ' getting data in the artId field ' converting to string ' display in the text box

which is equivalent to
txtArticleId.Text = dataTable.Rows(currRec)("artId").ToString()

Hence when you start the application and press the LoadTable button, you will see the following output:

How do I navigate through the records?


Navigating through the records is again very easy. For the Next button, we have written the following simple event handler
Private Sub btnNext_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnNext.Click currRec += 1 If currRec >= totalRec Then currRec = 0 End If FillControls() End Sub

Here we first increment the integer variable currRec and check if it has crossed the last record (using the totalRec variable) in the table. If it has, then we move the current record to the first record. We then call the FillControls() method to display the current record on the form. Similarly the event handler for the Previous button looks like this:
Private Sub btnPrevious_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnPrevious.Click currRec -= 1

If currRec < totalRec Then currRec = totalRec - 1 End If FillControls() End Sub

Here we decrement the currRec variable and check if has crossed the first record and if it has then we move it to the last record. Once again, we call the FillControls() method to display the current record. Now you can navigate through the records using the Next and Previous buttons.

How do I update tables in the dataset?


Updating a table in ADO.Net is very interesting and easy. You need to follow these steps to update, insert and delete records: The Data Adapter class (SqlDataAdapter) has properties for each of the insert, update and delete commands. First of all we need to prepare the command (SqlCommand) and add it to the data adapter object. The commands are simple SQL commands with parameters. You may use the Visual Studio .Net designer to easily create these commands. Secondly we need to add parameters to these commands. The parameters are simply the names of the data table fields involved in the particular command. Visual Studio .Net also build it for you in its Data Adapter configuration wizard. The two steps described above are done only once in the application. For each insert, update and delete; we insert, update and delete the corresponding data row (DataRow) of the data table (DataTable) object.

After any update we call the Update() method of the data adapter class by supplying to it, the dataset and table name as parameters. This updates our local dataset. Finally we call the AcceptChanges() method of the dataset object to store the changes in the dataset to the physical database.

How do I use a CommandBuilder object to prepare the update commands in my dataset?


Each data provider has a command builder object that prepares the update, insert and delete commands for you. You can use these (SqlCommandBuilder, OracleCommandBuilder, OleDbCommandBuilder, OdbcCommandBuilder) objects to generate commands automatically using the Select command you specified when defining the data adapter. In the following code, we have created and set the update, insert and delete commands using the SqlCommandBuilder object

C# Version
SqlConnection conn = new SqlConnection("server=FARAZ; database=programmersheaven; uid=sa; pwd=;"); string cmdStr = "select * from article"; SqlDataAdapter da = new SqlDataAdapter(cmdStr, conn);

DataSet ds = new DataSet(); da.Fill(ds, "Article");

SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da); da.InsertCommand = cmdBuilder.GetInsertCommand(); da.UpdateCommand = cmdBuilder.GetUpdateCommand(); da.DeleteCommand = cmdBuilder.GetDeleteCommand();

VB.Net Version
Dim conn As New SqlConnection("server=FARAZ; database=programmersheaven; uid=sa; pwd=;") Dim cmdStr As String cmdStr = "select * from article" Dim da As New SqlDataAdapter(cmdStr, conn) Dim ds As New DataSet da.Fill(ds, "Article") Dim cmdBuilder As New SqlCommandBuilder(da) da.InsertCommand = cmdBuilder.GetInsertCommand() da.UpdateCommand = cmdBuilder.GetUpdateCommand()

da.DeleteCommand = cmdBuilder.GetDeleteCommand()

What are the general steps for updating the records in dataset?
The Data Adapter class (SqlDataAdapter) has properties for each of the insert, update and delete commands. First of all we need to prepare the command (SqlCommand) and add it to the data adapter object. Secondly we need to add parameters to these commands. The two steps described above are done only once in the application. For each insert, update and delete; we insert, update and delete the corresponding data row (DataRow) of the data table (DataTable) object. After any update we call the Update() method of the data adapter class by supplying to it, the dataset and table name as parameters. This updates our local dataset. Finally we call the AcceptChanges() method of the dataset object to store the changes in the dataset to the physical database.

How do I update the dataset with the updates in records?


You can update the dataset by calling the Update() method of the data adapter.

C# Version
DataTable dt = ds.Tables["Article"]; dt.Rows[2]["lines"] = 600; da.Update(ds, "Article");

VB.Net Version
Dim dt = ds.Tables("Article") dt.Rows(2)("lines") = 700 da.Update(ds, "Article")

Here da and ds are the references of the DataAdapter and DataSet objects respectively.

How do I update the physical database with the changes in the dataset?
You can update the physical database by calling the AcceptChanges() method of the data set.

C# Version
DataTable dt = ds.Tables["Article"]; dt.Rows[2]["lines"] = 600; da.Update(ds, "Article"); ds.AcceptChanges();

VB.Net Version
Dim dt = ds.Tables("Article")

dt.Rows(2)("lines") = 700 da.Update(ds, "Article") ds.AcceptChanges()

Here da and ds are the references of the DataAdapter and DataSet objects respectively.

How do I update a record in the table using ADO.Net dataset?


Once you have the UpdateCommand prepared in the data adapter, you can update individual records simply by updating the field values in the data tables rows. The above code demonstrate how we can update the lines field of the third record of the table Article

C# Version
DataTable dt = ds.Tables["Article"]; dt.Rows[2]["lines"] = 600; da.Update(ds, "Article"); ds.AcceptChanges();

VB.Net Version
Dim dt = ds.Tables("Article") dt.Rows(2)("lines") = 700 da.Update(ds, "Article") ds.AcceptChanges()

How do I insert a record in the table using ADO.Net dataset?


To insert a record in the data table, you create an object of the DataRow using the DataTable object. Then you set the appropriate field values and finally add it to the DataTables Rows collection.

C# Version
DataTable dt = ds.Tables["Article"]; // Insert DataRow dr = dt.NewRow(); dr[0] = 4; dr[1] = "MFC Programming"; dr[2] = "VC++ MFC Library"; dr[3] = 3; dr[4] = 3000; dr[5] = DateTime.Parse("8/14/1999"); dt.Rows.Add(dr);

da.Update(ds, "Article"); ds.AcceptChanges();

VB.Net Version
Dim dt As DataTable dt = ds.Tables("Article") Insert Dim dr As DataRow dr = dt.NewRow() dr(0) = 4 dr(1) = "MFC Programming" dr(2) = "VC++ MFC Library" dr(3) = 3 dr(4) = 3000 dr(5) = DateTime.Parse("8/14/1999") dt.Rows.Add(dr) da.Update(ds, "Article") ds.AcceptChanges()

How do I delete a record in the table using ADO.Net dataset?


To delete a record, you first get the DataRow object from the DataTable object. Then you simply call the Delete() method of the data row object to delete a record from the data table.

C# Version
DataTable dt = ds.Tables["Article"]; // Delete DataRow dr = dt.Rows[3]; dr.Delete(); da.Update(ds, "Article"); ds.AcceptChanges();

VB.Net Version
Dim dt As DataTable

dt = ds.Tables("Article") Delete Dim dr As DataRow dr = dt.Rows(3) dr.Delete() da.Update(ds, "Article") ds.AcceptChanges()

What is the architecture of connected environment of data access in ADO.Net?


The connected environment of data access is the traditional procedure for accessing data programmatically. The differentiating property of the connected data access environment is that here you (the programmer) is required to manage the connection with the database. You can only perform database operations when, there exists an open connection to the database. Hence, before performing any database operation (select, update, insert, delete), the programmer opens a database connection and close the database connection after performing the database operations. The important objects for working in the connected environment are: Connection (SqlConnection, OleDbConnection, etc): It represents a connection to the database. All the connection objects in the ADO.Net implement the System.Data.IDbConnection interface. Command (SqlCommand, OleDbCommand, etc): It represents the SQL command sent to the database, e.g., SELECT, UPDATE, INSERT, DELETE. All commands in ADO.Net implements IDbCommand interface DataReader (SqlDataReader, OleDbDataReader, etc): It represents a data stream that can be used to read the result of your query returned by the database server. Using this object, you read the individual records and their fields returned as a result of your query to the database server. All the data readers in ADO.Net implement the System.Data.IDataReader interface.

How do I read data (or records) from database using data reader?
To read data from the database, you first make a connection object (SqlConnection, etc) and open it.

C# Version
string connString = "server=FARAZ; database=programmersheaven; uid=sa; pwd="; SqlConnection conn = new SqlConnection(connString); conn.Open();

VB.Net Version
Dim connString As String = "server=siraj; database=programmersheaven; uid=sa; pwd=" Dim conn As New SqlConnection(connString)

conn.Open()

Then you create a command using this connection and the command text.

C# Version
string cmdString = "select * from author"; SqlCommand cmd = new SqlCommand(cmdString, conn);

VB.Net Version
Dim cmdString As String = "select * from author" Dim cmd As New SqlCommand(cmdString, conn)

Then you execute the command with the command objects ExecuteReader() method. The ExecuteReader method returns the object of type IDataReader

C# Version
SqlDataReader reader = cmd.ExecuteReader();

VB.Net Version
Dim reader As SqlDataReader = cmd.ExecuteReader()

Now you read the individual records using this data reader. To advance to the next record, you call its Read() method which returns Boolean to indicate if there exists a next row. If the DataReaders Read() method returns true then the DataReader acts as a database row (record). Now you can access the fields of this particular row specifying the column names (or integral indexes) in its indexers.

C# Version
while(reader.Read()) { txtData.Text += reader["authorId"].ToString(); txtData.Text += ", "; txtData.Text += reader["name"].ToString(); txtData.Text += "\r\n"; }

VB.Net Version
While reader.Read() txtData.Text += reader("authorId").ToString() txtData.Text += ", " txtData.Text += reader("name").ToString() txtData.Text += vbCrLf End While

Finally, you need to close the database connection opened before performing the database operation (SELECT, in our case)

C# Version
conn.Close();

VB.Net Version
conn.Close()

Lets look at the complete code now for review

C# Version
string connString = "server=siraj; database=programmersheaven;" + "uid=sa; pwd="; SqlConnection conn = new SqlConnection(connString); string cmdString = "select * from author"; SqlCommand cmd = new SqlCommand(cmdString, conn); conn.Open(); SqlDataReader reader = cmd.ExecuteReader(); while(reader.Read()) { txtData.Text += reader["authorId"].ToString(); txtData.Text += ", "; txtData.Text += reader["name"].ToString(); txtData.Text += "\r\n"; } conn.Close();

VB.Net Version
Dim connString As String = "server=siraj; database=programmersheaven;" + _ "uid=sa; pwd=" Dim conn As New SqlConnection(connString) Dim cmdString As String = "select * from author" Dim cmd As New SqlCommand(cmdString, conn) conn.Open() Dim reader As SqlDataReader = cmd.ExecuteReader() While reader.Read() txtData.Text += reader("authorId").ToString()

txtData.Text += ", " txtData.Text += reader("name").ToString() txtData.Text += vbCrLf End While conn.Close()

How do I insert records using data reader?


The procedure for updating records using INSERT commands is very similar to the one we presented in the previous example (of SELECT) except that here the command does not return anything and thus the method to call on the SqlCommand object is called ExecuteNonQuery().

C# Version
string connString = "server=FARAZ; database=programmersheaven;" + "uid=sa; pwd="; SqlConnection conn = new SqlConnection(connString);

// INSERT Query string cmdString ="INSERT INTO Author " + "(authorId, name) " + "VALUES(3, 'Anders Hejlsberg')";

SqlCommand cmd = new SqlCommand(cmdString, conn);

conn.Open(); cmd.ExecuteNonQuery(); conn.Close();

VB.Net Version
Dim connString As String = "server=FARAZ; database=programmersheaven;" + _ "uid=sa; pwd=" Dim conn As New SqlConnection(connString)

' INSERT Query

Dim cmdString As String = "INSERT INTO Author " + _ "(authorId, name) " + _ "VALUES(3, 'Anders Hejlsberg')"

Dim cmd As New SqlCommand(cmdString, conn)

conn.Open() cmd.ExecuteNonQuery() conn.Close()

How do I update records using data reader?


The procedure for updating records using INSERT commands is very similar to the one we presented in the previous example (of SELECT) except that here the command does not return anything and thus the method to call on the SqlCommand object is called ExecuteNonQuery().

C# Version
string connString = "server=FARAZ; database=programmersheaven;" + "uid=sa; pwd="; SqlConnection conn = new SqlConnection(connString);

// UPDATE Query string cmdString = "UPDATE Author " + "SET name = 'Grady Booch' " + "WHERE authorId = 3";

SqlCommand cmd = new SqlCommand(cmdString, conn);

conn.Open(); cmd.ExecuteNonQuery(); conn.Close();

VB.Net Version
Dim connString As String = "server=FARAZ; database=programmersheaven;" + _

"uid=sa; pwd=" Dim conn As New SqlConnection(connString)

' UPDATE Query Dim cmdString As String = "UPDATE Author " + _ "SET name = 'Grady Booch' " + _ "WHERE authorId = 3"

Dim cmd As New SqlCommand(cmdString, conn)

conn.Open() cmd.ExecuteNonQuery() conn.Close()

How do I delete records using data reader?


The procedure for updating records using INSERT commands is very similar to the one we presented in the previous example (of SELECT) except that here the command does not return anything and thus the method to call on the SqlCommand object is called ExecuteNonQuery().

C# Version
string connString = "server=FARAZ; database=programmersheaven;" + "uid=sa; pwd="; SqlConnection conn = new SqlConnection(connString);

// DELETE Query string cmdString = "DELETE FROM Author " + "WHERE authorId = 3";

SqlCommand cmd = new SqlCommand(cmdString, conn);

conn.Open();

cmd.ExecuteNonQuery(); conn.Close();

VB.Net Version
Dim connString As String = "server=FARAZ; database=programmersheaven;" + _ "uid=sa; pwd=" Dim conn As New SqlConnection(connString)

' DELETE Query Dim cmdString As String = "DELETE FROM Author " + "WHERE authorId = 3"

Dim cmd As New SqlCommand(cmdString, conn)

conn.Open() cmd.ExecuteNonQuery() conn.Close()

How do I write common code for different dot net framework data providers?
The System.Data namespace contains the interfaces implemented by different dot net framework data providers, such as: IDbConnection implemented by SqlConnection, OracleConnection, OleDbConnection, OdbcConnection classes represents a connection with the database server IDbCommand implemented by SqlCommand, OracleCommand, OleDbCommand, OdbcCommand classes represents an SQL command passed to the database server IDbDataAdapter implemented by SqlDataAdapter, OracleDataAdapter, OleDbDataAdapter, OdbcDataAdapter classes represents a data adapter used to fill the data set in the disconnected environment of the ADO.Net IDataReader implemented by SqlDataReader, OracleDataReader, OleDbDataReader, OdbcDataReader classes represents a data reader used to read records from the database server, analogous to read only, forward only cursor IDbTransaction implemented by SqlTransaction, OracleTransaction, OleDbTransaction, OdbcTransaction classes represents a transaction established with the database server

We strongly recommend the readers to use the references of these interface type to perform the database operations wherever possible. Using these, you can write a code that is data provider independent. Consider a data access module which is supplied the database connection and which performs the

database operations using this connection. This module does not know which data provider the connection belongs and uses the interface approach. Following code demonstrate this data access module

C# Version
internal class DataAccessModule { private IDbConnection conn; private IDbCommand cmd;

private const string GetValueCmdText ="SELECT value FROM MyTable WHERE name = '";

public DataAccessModule(IDbConnection conn) { this.conn = conn; cmd = conn.CreateCommand(); conn.Open(); }

public string GetValue(string name) { cmd.CommandText = GetValueCmdText + name + "'"; IDataReader reader = cmd.ExecuteReader(); if(reader.Read()) { return reader["value"].ToString(); } else { return null; }

// more functions... }

VB.Net Version
Friend Class DataAccessModule

Private conn As IDbConnection Private cmd As IDbCommand

Private Const GetValueCmdText As String ="SELECT value FROM MyTable WHERE name = '"

Public Sub New(ByVal conn As IDbConnection) Me.conn = conn cmd = conn.CreateCommand() conn.Open() End Sub

Public Function GetValue(ByVal name As String) As String cmd.CommandText = GetValueCmdText + name + "'" Dim reader As IDataReader = cmd.ExecuteReader() If (reader.Read()) Then Return reader("value").ToString() Else Return Nothing End If End Function

' More Functions....

End Class

What is a stored procedure?


A stored procedure is a precompiled executable object that contains one or more SQL statements. A stored procedure may be written to accept inputs and return output.

What is the advantage of using stored procedure over the SQL queries?
Writing the SQL statements inside our code is usually not a good idea. In this way you expose your database schema (design) in the code which may be changed. Hence most of the time programmers use stored procedures instead of plain SQL statements. A stored procedure is a precompiled executable object that contains one or more SQL statements. Hence you can replace your complex SQL statements with a single stored procedure. Since, stored procedures are precompiled objects they execute faster at the database server. Most of the time, stored procedures contain more than one command; in this case, the time to pass the individual commands to the database server from the program is saved. The database is issued just one command (to execute the stored procedure) and the DB server executes all the commands and returns the result in the end. Hence, the overall interaction time with the DB server reduces in a great deal. This can result in a huge optimization in case where the DB server is accessed via a slow network.

How do stored procedure look like, can you provide some sample stored procedures?
Here we are presenting a brief review of four basic type of stored procedure for SELECT, INSERT, UPDATE and DELETE operations. In SQL Server, you can create and add stored procedures to your database using the SQL Server Enterprise Manager.

UPDATE Stored Procedure


A simple stored procedure to update a record is
CREATE PROCEDURE UpdateProc ( @artId as int, @title as varchar(100), @topic as varchar(100), @authorId as int, @lines as int, @dateOfPublishing as datetime) AS UPDATE Article SET title=@title, topic=@topic, authorId=@authorId, lines=@lines, dateOfPublishing=@dateOfPublishing

WHERE artId=@artId GO

The name of stored procedure is UpdateProc and it has the input parameters for each of the fields of our Article table. The query to be executed when the stored procedure is run updates the record with the supplied primary key (@artId) using the supplied parameters. It is very similar to the code we have written to initialize command in the previous example and we hope you dont have any problem in understanding this even you are not familiar with stored procedure.

INSERT Stored Procedure


A simple stored procedure to insert a record is
CREATE PROCEDURE InsertProc ( @artId as int, @title as varchar(100), @topic as varchar(100), @authorId as int, @lines as int, @dateOfPublishing as datetime) AS INSERT INTO article (artId, title, topic, authorId, lines, dateOfPublishing) VALUES(@artId, @title, @topic, @authorId, @lines, @dateOfPublishing) GO

The stored procedure above is named InsertProc and is very similar to the UpdateProc except that here we are using the INSERT SQL statement instead of the UPDATE command.

DELETE Stored Procedure


A simple stored procedure to delete a record is
CREATE PROCEDURE DeleteProc (@artId as int) AS DELETE FROM article WHERE artId = @artId GO

Here we have used only one parameter as to delete a record you only need its primary key value.

SELECT Stored Procedure


A simple stored procedure to delete a record is
CREATE PROCEDURE SelectProc AS SELECT * FROM Article GO

This probably is the simplest of all. It does not take any parameter and only selects all the records from the Article table. All the four stored procedures presented above are kept extremely simple so that the reader does not find any difficulty in understanding the use of stored procedure in his C#/VB.Net code. The real world stored procedures are much more complex and off course useful than these!

How do I call a stored procedure from my application using ADO.Net?


Using stored procedures with ADO.Net in C# is extremely simple, especially when we have developed the application with SQL commands. All we need is: Create a command object (SqlCommand, etc) and specify the stored procedure name Set the CommandType property of the command object to the CommandType.StoredProcedure enumeration value. This tells the runtime that the command used here is a stored procedure.

Thats it! The sample code to use with data adapter is:

C# Version
// Preparing Insert SQL Command SqlCommand insertCommand = new SqlCommand("InsertProc", conn); insertCommand.CommandType = CommandType.StoredProcedure; dataAdapter.InsertCommand = insertCommand; insertCommand.UpdatedRowSource = UpdateRowSource.None; ...

VB.Net Version
' Preparing Insert SQL Command Dim insertCommand = New SqlCommand("InsertProc", conn) insertCommand.CommandType = CommandType.StoredProcedure dataAdapter.InsertCommand = insertCommand insertCommand.UpdatedRowSource = UpdateRowSource.None

How do I make my first application to call stored procedure using ADO.Net?


Please download the attached source code for the sample application using the stored procedures to access the data with ADO.Net in VB and C#.

What are the important points when developing a data access app with ADO.Net?
Always try to use the base interfaces for connection, command, data reader and other objects.

Always try to use the SqlClient, SqlServerCe and OracleClient to connect with the Sql Server, Sql Server CE and Oracle Database servers as they are specialized and optimized for the specific database servers. Still remember to reference the data provider specific objects (SqlConnection, OracleCommand) to reference with the base interface (IDbConnection, IDbCommand)

C# Version
IDbConnection conn = new SqlConnection(); ... IDbCommand cmd = new OracleCommand();

VB.Net Version
Dim conn As IDbConnection conn = New SqlConnection(); ... Dim cmd As IDbCommand cmd = new OracleCommand();

Do not write the connection string in your code as it may change. Either write it in a text file or an xml file and read it on the application startup. For security purposes, you may also write the encrypted connection string in the text/xml file Try to use the stored procedures wherever possible especially when you are to write a series of queries whose individual results are not required to be used in the code in between this series of queries. Do not use the complex queries in the source code. If the query is getting complex, try to make the views inside the database server and use the views instead. Practice using the transactions when it makes sense, especially with error handling codes Put special consideration in the error handling code. The database operation may fail due to various reasons such as invalid connection string, invalid table/field name in the query, database server failure, connection failure, too many connections on the server or the server busy, invalid query, etc You need to consider all these while writing the code for error handling. Using Visual Studio.Nets debugger is a very good and useful practice to find the possible errors. Remember, Ado.Net exception messages are not much useful (or quite vague) in general for debugging; hence the use of watch and quick watch debugger windows is extremely useful and helpful in when debugging the code. When using dataset and disconnected architecture, we dont update the data source (by calling DataAdapters Update() method and DataSets AcceptChanges() method) for each update. Instead we make the changes local and update all these changes later as a batch. This provides optimized use of network bandwidth. BUT, this off course is not a better option when multiple users are updating the same database. When changes are not to be done locally and need to be reflected at database server at the same time, it is preferred to use the connected oriented environment for all the changes (UPDATE, INSERT and DELETE) by calling the ExecuteNonQuery() method of your command (SqlCommand or OleDbCommand) object. Disconnected data access is suited most to read only services. In common practice clients are often interested in reading and displaying data. In this type of situation, the disconnected data access excels as it fetches the whole data in a single go and store it in the local buffer (dataset). This local storage of data eliminates the need of staying connecting to the database and fetching single record at a time. On the down side, disconnected data access architecture is not designed to be

used in the networked environment where multiple users are updating data simultaneously and each of them needs to be aware of current state of database at any time (e.g., Airline Reservation System).

What is data grid and what is the use of it?


Data Grid is the standard control for viewing data in .Net environment. A data grid control is represented in .Net by System.Windows.Forms.DataGrid class. The data grid control can display the data from a number of data sources e.g. data table, dataset, data view and array.

How can I make my first application with DataGrid using the data from ADO.Net?
Lets create a simple application first that loads a table data from database server to the data grid control. First of all, add a data grid control and a button to your form from Visual Studio toolbox. We have set the Name property of data grid to dgDetails and its CaptionText property to ProgrammersHeaven Database. The name of button is btnLoadData. The event handler for button is:

C# Version
private void btnLoadData_Click(object sender, System.EventArgs e) { string connectionString = "server=FARAZ; database=programmersheaven;" + "uid=sa; pwd=;"; SqlConnection conn = new SqlConnection(connectionString); string cmdString = "SELECT * FROM article"; SqlDataAdapter dataAdapter = new SqlDataAdapter(cmdString, conn); DataSet ds = new DataSet(); dataAdapter.Fill(ds, "article");

dgDetails.SetDataBinding(ds, "article"); }

VB.Net Version
Private Sub btnLoadData_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnLoadData.Click

Dim connectionString As String = "server=P-III; database=programmersheaven;" + _ "uid=sa; pwd=;" Dim conn As New SqlConnection(connectionString) Dim cmdString As String = "SELECT * FROM article"

Dim dataAdapter As New SqlDataAdapter(cmdString, conn) Dim ds As New DataSet() dataAdapter.Fill(ds, "article")

dgDetails.SetDataBinding(ds, "article")

End Sub

Here we first created data adapter and filled the data set using it as we used to do in other applications. The only new thing is the binding of article table to the data grid control which is done by calling the SetDataBinding() method of the DataGrid class. The first parameter of this method is the dataset while the second parameter is the name of table in the dataset.

C# Version
dgDetails.SetDataBinding(ds, "article");

VB.Net Version
dgDetails.SetDataBinding(ds, "article")

When you execute this program and select the Load button you will see the output presented in the previous figure.

How can I make my data grid to view data from multiple related tables?
Lets see how we can use Data Grid control to show multiple related tables. When two tables are related, one is called the parent table while the other is called the child table. The child table contains the primary key of parent table as a foreign key. For example in our ProgrammersHeaven database, table Author is the parent table of the Article table as the Article table contains AuthorId as foreign key which is a primary key in the Author table. In this example, we will use data grid to show the related records from article and author table. In order to specify the relationship between the two tables we need to use the DataRelation class as:

C# Version
dgDetails.SetDataBinding(ds, "article") DataRelation relation = new DataRelation("ArtAuth", ds.Tables["author"].Columns["authorId"], ds.Tables["article"].Columns["authorId"] );

VB.Net Version
Dim relation As New DataRelation("ArtAuth", _ ds.Tables("author").Columns("authorId"), _ ds.Tables("article").Columns("authorId") _

Here the first argument of DataRelation constructor is the name for the new relation while second and third arguments are the columns of the tables which will be used to relate the two tables. After creating this relationship we need to add it to the Relations collection of the dataset.

C# Version
ds.Relations.Add(relation);

VB.Net Version
ds.Relations.Add(relation)

Hence the modified code for the Load Data button is:

C# Version
private void btnLoadData_Click(object sender, System.EventArgs e) { string connectionString = "server=P-III; database=programmersheaven;" + "uid=sa; pwd=;"; SqlConnection conn = new SqlConnection(connectionString);

string cmdString = "SELECT * FROM article"; SqlDataAdapter dataAdapter = new SqlDataAdapter(cmdString, conn); DataSet ds = new DataSet(); dataAdapter.Fill(ds, "article");

cmdString = "SELECT * FROM author"; dataAdapter = new SqlDataAdapter(cmdString, conn); dataAdapter.Fill(ds, "author");

DataRelation relation = new DataRelation("ArtAuth", ds.Tables["author"].Columns["authorId"], ds.Tables["article"].Columns["authorId"] ); ds.Relations.Add(relation);

DataView dv = new DataView(ds.Tables["author"]); dgDetails.DataSource = dv; }

VB.Net Version
Private Sub btnLoadData_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnLoadData.Click

Dim connectionString As String = "server=P-III; database=programmersheaven;" + _ "uid=sa; pwd=;" Dim conn As New SqlConnection(connectionString) Dim cmdString As String = "SELECT * FROM article" Dim dataAdapter As New SqlDataAdapter(cmdString, conn) Dim ds As New DataSet() dataAdapter.Fill(ds, "article")

cmdString = "SELECT * FROM author" dataAdapter = New SqlDataAdapter(cmdString, conn) dataAdapter.Fill(ds, "author")

Dim relation As New DataRelation("ArtAuth", _ ds.Tables("author").Columns("authorId"), _ ds.Tables("article").Columns("authorId") _ ) ds.Relations.Add(relation)

Dim dv As New DataView(ds.Tables("author")) dgDetails.DataSource = dv End Sub

In the above code we first filled the dataset with the two tables, defined the relationship between them and then added it to the dataset. In the last two lines, we created an instance of DataView class by supplying the parent table in its constructor call and then set the DataSource property of data grid to this data view. When we compile and execute this application, the data grid will show the records of parent table with + button on the left of each record

When you press the + button on the left of the record, it will expand to show the name of relationship as a link

Now when you click the relation name, the data grid will show all the related records in the child table

Still you can see the parent record at the top of all the rows of the child table. You can go back to the parent table using the back arrow button () at the title bar of the data grid.

What are the issues related to the deployment of data access application?
Some of the basic issues related to the deployment of the data access applications are: Can we suppose the required database exists at the target location? If the database does exist then how can we get the connection string of it? Should we get it at the installation time? Or at the first run? If the database does not exist then how it can be created? Is it the responsibility of human installing our application? Or the application should create it at the time of installation? If the database is to be created by the application installation, then how does the installation setup know where (on which machine) to create the database? And what user name and password the setup should use to create the database? Once, the database is created or its connection string is found at the setup time, then how to store the connection string for later use (regular execution)? What if the database address (connection string) is changed during the application life cycle then what should be the application behavior? How can the application be aware of the new connection string? If the database schema is hard-coded in the code (like table and field names) and the DB schema is changed (table/field name or data type is changed or new field/table added or some fields/tables deleted) because of any reason, then how to fix this problem?

You can see from the above points that the basic issue is the identification of the address (or connection string) of the database server. The most important point to remember here is that the application must perform in any condition and must not be crashed because of any condition and most of the problems (if not all) should be handled without any change in the code or any update patch installation

How do I solve the deployment issues (mentioned in the previous FAQ)?


Ok, lets discuss some of the issues and their solution briefly. The specific detail of these solutions is given in the next FAQs.

The easiest and very sound solution is to provide the database script to create necessary database and tables along with the installation and ask your user to run the script on the target database server to create the required database. Then ask the user to supply the connection string at the installation setup time. You can create the database with the installation by executing the database creation script with the installation. But before this, you have to ask the user the location (the computer on the network) where the database server exists, and the user name, password to login to the database. The connection string should be stored in a text or binary or xml file. You can also encrypt the connection string before writing it to the file. The application, thus, is required to decrypt and load the connection string in the memory at each startup. The application should load the connection string at each startup and attempt to connect to the database. If the connection attempt fails then it should inform the user that the database is not available and ask the user to setup the database and try again. The application should also allow the user to change the database connection string any time and, it the application logic permits, let the user specify to work without database. If the user specifies a new connection string during the application startup or regular execution, the application should save it for later use. One solution to the schema changed problem is to use views and stored procedure wherever possible. But if this is not done or the change is too big to be catered by the views and/or stored procedure then you can supply a new data access module update (a new DLL may be). For this reason, it is advised to separate the data access code in a separate physical and logical module (or assembly in .Net language) so you can change it without affecting the overall application. But when using this, the interface (the method signatures) should be made that abstract that they does not exactly map to the physical database schema but to the logical schema. Finally, if the database schema change is major (which is not a very good sign for the application overall design) then there is no solution but to change the code and ship the installation again!!!

How do I set the connection string at installation :specific data provider?


Well this is quite tricky and interesting. Connection strings are database dependent and different database servers allow connection strings in different formats. If you are using the database specific provider classes (like those from System.Data.SqlClient or System.Data.OracleClient) then you can generate the connection string easily by taking the specific inputs from the user. For example, if you are using SQL Server and the classes from the System.Data.SqlClient namespace then we can ask user the SQL Server instance name, the user name, password of if he/she is using the Windows Authentication to log in and the database name.

How do I set the connection string at installation :general data provider?


The problem arises when you are using the general data providers such as classes from System.Data.OleDb and System.Data.Odbc namespaces. You cant make a general GUI to generate the connection string for all the database servers. Then what to do now? The solution is the DataLink Dialog. You must have seen the dialog which looks like this in many windows applications:

So how you can use this dialog in your program? For this you need add a reference to COM component Microsoft OLE DB Service Component 1.0 Type Library which should be available if you have installed Microsoft ActiveX Data Components. Once you have added the component, you can show the Data Link Properties dialog box by making an object of type MSDASC.DataLink class and calling its PromptNew() method.

C# Version
MSDASC.DataLinks udl = new MSDASC.DataLinksClass(); udl.PromptNew();

VB.Net Version
Dim udl As MSDASC.DataLinks udl = New MSDASC.DataLinksClass udl.PromptNew()

The above code will show the Data Link Properties dialog box. But how can we get the connection string generated by the dialog box? The PromptNew() method returns a connection type object which can be captured in an object of type ADODB.Connection. Hence for this, add a reference to adodb .Net assembly in your project, and get the connection string using the ConnectionString property of this object. The following code snippets demonstrate this:

C# Version
string connStr = "";

MSDASC.DataLinks udl = new MSDASC.DataLinksClass(); ADODB.Connection conn = (ADODB.Connection) udl.PromptNew();

if(conn != null) { connStr = conn.ConnectionString; }

VB.Net Version
Dim connStr As String

Dim udl As MSDASC.DataLinks udl = New MSDASC.DataLinksClass Dim conn As ADODB.Connection = udl.PromptNew()

If Not conn Is Nothing Then connStr = conn.ConnectionString End If

You can use this code in the overrided Install() method of your projects installer class (the class derived from System.Configuration.Install.Installer class), and add the project output in the Custom Actions of the setup project.

How do I supply the connection string during first run or during the regular execution?
Well that should be very simple Just add the Data Link Properties dialog box at the start of the application or during the regular execution of the application whenever you need it. Alternatively, you can also provide your own designed user interface for connection string related properties, if your application supports specific .Net data providers (like System.Data.SqlClient or System.Data.OracleClient)

How do I store / retrieve the connection string in / from a text file?


You can store the connection string in the text file or an xml file and later retrieve it. Lets see some example code to write a connection string to the text file and read it back

C# Version
string connStr = "";

// get connection string in the connStr variable

// Write connection string to text file StreamWriter sw = new StreamWriter(@"C:\ConnectionString.txt"); sw.WriteLine(connStr);

// ...

// Read connection string from the text file StreamReader sr = new StreamReader(@"C:\ConnectionString.txt"); connStr = sr.ReadLine();

VB.Net Version
Dim connStr As String = ""

' get connection string in the connStr variable

' Write connection string to text file Dim sw As New StreamWriter("C:\ConnectionString.txt") sw.WriteLine(connStr)

' ...

' Read connection string from the text file Dim sr As New StreamReader("C:\ConnectionString.txt") connStr = sr.ReadLine()

How do I store / retrieve the connection string in / from an XML file?


Once you get the connection string, you can store the connection string in the text file or an xml file and later retrieve it. Lets see some example code to write a connection string to an XML file and read it back

C# Version
string connStr = "";

// get connection string in the connStr variable

// Write connection string to xml file XmlDocument xmlDoc = new XmlDocument(); XmlNode xn = xmlDoc.CreateNode(XmlNodeType.Element, "ConnectionString", ""); xn.InnerText = connStr; xmlDoc.AppendChild(xn); xmlDoc.Save(@"C:\ConnectionString.xml");

// ...

// Read connection string from the text file XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(@"C:\ConnectionString.xml"); XmlNode xn = xmlDoc.SelectSingleNode("ConnectionString"); connStr = xn.InnerText;

VB.Net Version
Dim connStr As String = ""

' get connection string in the connStr variable

' Write connection string to xml file Dim xmlDoc As New XmlDocument Dim xn As XmlNode xn = xmlDoc.CreateNode(XmlNodeType.Element, "ConnectionString", "") xn.InnerText = connStr

xmlDoc.AppendChild(xn) xmlDoc.Save("C:\ConnectionString.xml")

' ...

' Read connection string from the xml file Dim xmlDoc As New XmlDocument xmlDoc.Load("C:\ConnectionString.xml") Dim xn As XmlNode xn = xmlDoc.SelectSingleNode("ConnectionString") connStr = xn.InnerText

How do I make my first Hello, Data Access Application Deployment setup program?
We will start with the assumption that you have a data access application. Note that we are only providing here the C# example. The VB.Net example is exactly similar. Why we didnt include the VB.Net example? Because, the intent here is not to explain the code but the procedure of how to create the data accessing applications deployment project which is independent of the language being used. All the code we will present here has already been presented in the previous FAQs and explained in much detail. The first step, then, is to add an installer class. The easiest way to do is to right click the project icon in the solution explorer and select Add New Item and in the pop-up window, select Installer class, name it appropriately and select Open button to add it. Now right click the newly added installer class and select view code. You will notice that this new class is automatically inherited from the System.Configuration.Install.Installer class
public class Installer1 : System.Configuration.Install.Installer

The only thing you need to do now in this class is to override the Install() method of the base class, write the code you want to execute when the installation setup is executed. We have written the code to display the Data Link Properties dialog box and save the resulted connection string into an xml file, so later the application can use it.
public override void Install(IDictionary stateSaver) { base.Install (stateSaver); string connStr = "";

MSDASC.DataLinks udl = new MSDASC.DataLinksClass();

ADODB.Connection conn = (ADODB.Connection) udl.PromptNew();

if(conn != null) { connStr = conn.ConnectionString; }

// Write connection string to xml file XmlDocument xmlDoc = new XmlDocument(); XmlNode xn = xmlDoc.CreateNode(XmlNodeType.Element, "ConnectionString", ""); xn.InnerText = connStr; xmlDoc.AppendChild(xn); xmlDoc.Save(@"C:\ConnectionString.xml"); }

This is all for the setup, we have added a button to our database deployment application form which displays the connection string in a message box. It retrieves the connection string from the xml file generated by the installation setup program.
private void btnShowConnStr_Click(object sender, System.EventArgs e) { string connStr = "";

// Read connection string from the xml file XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(@"C:\ConnectionString.xml"); XmlNode xn = xmlDoc.SelectSingleNode("ConnectionString"); connStr = xn.InnerText; MessageBox.Show(connStr, "Connection String from XML file");

Now the application is ready. We will start building our setup project. For this, add a new Setup and Deployment project to the solution by right clicking the solution and selecting Add New Project in the pop-up window, selecting the Setup Project from the Setup and Deployment Projects section. Once the setup project is added to the solution, right click it in the solution explorer and select View-->File System. Here right click the application folder icon and select Project Output --> Primary Out put of your data access project. This will automatically add the project dependencies. Now right click the Primary Output of your project and create its short cut. Copy this shortcut to the Desktop folder and the User Program Menu and rename shortcut appropriately.

Now to ask the setup project run our custom installation code (we have written in the Installer class in the data access application), we need to add the primary output of our project to the custom actions of the setup project. To do this, right click the setup project in the solution explorer, and select View --> Custom Actions. Here right click Install and select Add Custom Action. In the popup window, select the primary output of the database access application from the application folder and click OK.

This is all we need to do! Rebuild the solution and remove any minor bugs (if they do popup). When your setup project will be built, it will generate a Setup.exe file in its debug (or release folder depending on the project configuration). Run this setup.exe to install this application. The setup will ask you the connection string and save it in the xml file.

After installation is complete, run the application using its desktop icon. When you will click the button on the form, it will read the connection string from the xml file and display it in the message box.

How to use relation objects in a dataset?


DataSet's that contain multiple DataTable objects can use DataRelation objects to relate one table to another. Adding a DataRelation to a DataSet adds by default a UniqueConstraint to the parent table and a ForeignKeyConstraint to the child table. The code sample below creates a DataRelation using two DataTable objects in a DataSet. Each DataTable contains a column named CustID which serves as a "relation" between two the DataTable objects. The example adds a single DataRelation to the Relations collection of the DataSet. The first argument in the sample specifies the name of the DataRelation being created. The second argument sets the parent DataColumn and the third argument sets the child DataColumn.
custDS.Relations.Add("CustOrders", custDS.Tables["Customers"].Columns["CustID"], custDS.Tables["Orders"].Columns["CustID"]);

OR
private void CreateRelation() { DataColumn parentCol; DataColumn childCol;

parentCol = DataSet1.Tables["Customers"].Columns["CustID"]; childCol = DataSet1.Tables["Orders"].Columns["CustID"];

DataRelation relCustOrder; relCustOrder = new DataRelation("CustomersOrders",

parentCol, childCol);

DataSet1.Relations.Add(relCustOrder);

DataReader Vs DataSet?
The ADO.NET DataReader is used to retrieve "read-only" / "forward-only" data from a database. Using the DataReader increases application performance and reduces system overheads. This is due to one row

at a time is stored in memory. You create a DataReader by calling Command.ExecuteReader after creating an instance of the Command object. The following line of code is used to retrieve rows from a data source.
SqlDataReader myReader = myCommand.ExecuteReader();

The Read method of the DataReader object is used to obtain a row from the results of the query, like so.
(myReader.Read()) Console.WriteLine("\t{0}\t{1}",

myReader.GetInt32(0), myReader.GetString(1)); myReader.Close();

The DataSet is a in-memory representation of data that provides a consistent relational programming model regardless of the data source. It can be used with multiple data sources. The DataSet represents a complete set of data including related tables, constraints, and relationships among the tables. The methods and objects in a DataSet are consistent with those in the relational database model. The DataSet can also persist and reload its contents as XML and its schema as XML Schema definition language (XSD) schema. The DataAdapter acts as a bridge between a DataSet and a data source for retrieving and saving data. The DataAdapter provides this bridge by "mapping Fill". Which changes the data in the DataSet to match the data in the data source. Upon this an Update occurs, which changes the data in the data source to match the data in the DataSet. On connecting to a Microsoft ?SQL Server database, an increase in overall performance can be obtained by using the SqlDataAdapter along with its associated SqlCommand and SqlConnection. For other OLE DB-supported databases, use the DataAdapter with its associated OleDbCommand and OleDbConnection.

How do I access a SQL stored procedure?


You can access SQL stored procedures the same way as executing other SQL commands. Set the query string as the name of the stored procedure and then set the CommandType to be CommandType.StoredProcedure. Below is an example of one input and one output parameter.
if(myConn.State == ConnectionState.Closed)myConn.Open(); SqlCommand myCmd = new

SqlCommand("sp_my_stored_procedure",myConn); myCmd.CommandType = CommandType.StoredProcedure;

SqlParameter parm; parm = myCmd.Parameters.Add(new SqlParameter("@custid",

SqlDbType.VarChar,50)); parm.Direction = ParameterDirection.Input; myCmd.Parameters["@custid"].Value = OrderID;

parm = myCmd.Parameters.Add(new SqlParameter("@custName",

SqlDbType.VarChar,50)); parm.Direction = ParameterDirection.Output;

SqlDataAdapter da = new SqlDataAdapter(); da.TableMappings.Add("your mapping","your mapping"); da.SelectCommand = myCmd; DataSet ds = new DataSet(); da.Fill(ds); DataTable resultTable = ds.Tables[0];

Methods of the Command Objects with databases?


The Command object is represented by two corresponding classes: SqlCommand and OleDbCommand. Command objects are used to execute statements (commands) to a database via a data connection. The Command objects can be used to execute stored procedures on the Database, SQL statements, or return complete tables directly. Command objects provide three methods that are used to execute commands on the database: ExecuteNonQuery. Executes direct SQL commands, such as INSERT, UPDATE or DELETE. ExecuteScalar. Returns a single value from a Database Query. ExecuteReader. Returns a result set by way of a DataReader object.

How do I display a data table in a data grid?


The following code queries an MS Access Table, then displays all the columns of that table in a Data Grid.
'Establish a connection to the data source. Dim ConnString As String

ConnString = "Provider=Microsoft.Jet.OLEDB.4.0;" &

"Data Source=C:\Test.mdb"

Dim Conn As New System.Data.OleDb.OleDbConnection(ConnString) Conn.Open() Dim dapt As New System.Data.OleDb.OleDbDataAdapter("Table1", Conn)

Dim dst As New DataSet

dapt.Fill(dst, "Table1")

DataGrid1.SetDataBinding(dst, "Table1")

Conn.Close()

Upon running the above code, Table1 from the a "Test" database will be displayed in a DataGrid.

How do I insert data entered in a textbox into the database?


The data you enter in the textboxes will be inserted into the database when of the click of a Button. The working senario is a database called "Emp" with a table named "Table1" with three columns. Also a Form with three TextBoxes and one Command Button.
Imports System.Data.OleDb Dim cn As OleDbConnection Dim cmd As OleDbCommand Dim dr As OleDbDataReader Dim icount As Integer Dim str As String

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As Button2.Click

System.EventArgs) Handles_

Try cn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\emp.mdb;Persist Security_ Info=False")

cn.Open()

str = "insert into table1 values(" & CInt(TextBox1.Text) TextBox3.Text & "')" 'string stores the command 'and CInt is used to convert number, to string

&

",'"

&

TextBox2.Text

&

"','"

&

cmd = New OleDbCommand(str, cn) icount = cmd.ExecuteNonQuery

MessageBox.Show(icount) 'displays number of records inserted Catch

End Try

End Sub

How do I access SQL server in VB.NET?


To access data from a table in ?SQL Server you need to import the namespace System.Data.SqlClient and establish a connection from the application to the server. The following code demonstrates how to connect to a ?SQL Server and display data from the "Discounts" table in the sample database "PUBS".

Imports System.Data.SqlClient

Public Class Form1 Inherits System.Windows.Forms.Form

Dim myConnection As SqlConnection Dim myCommand As SqlCommand Dim dr As New SqlDataReader()

'declaring the objects need Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As_

System.EventArgs) Handles MyBase.Load

myConnection = New SqlConnection("server=localhost;uid=sa;pwd=;database=pubs") 'establishing connection

Try myConnection.Open() 'opening the connection myCommand = New SqlCommand("Select * from discounts", myConnection)

'executing the command and assigning it to connection dr = myCommand.ExecuteReader()

While dr.Read() 'reading from the datareader MessageBox.Show("discounttype" & dr(0).ToString()) MessageBox.Show("stor_id" & dr(1).ToString()) MessageBox.Show("lowqty" & dr(2).ToString()) MessageBox.Show("highqty" & dr(3).ToString()) MessageBox.Show("discount" & dr(4).ToString()) 'displaying the data from the table End While

dr.Close() myConnection.Close()

Catch e As Exception End Try

End Sub End Class

How to insert an image in Access Database?


The following code asks for a path of a Gif image. Then inserts the Gif image to an Access database.

File name is Image.vb

Imports System Imports System.IO Imports System.Data

Public Class SaveImage Shared Sub main()

Dim o As System.IO.FileStream Dim r As StreamReader Dim gifFile As String

Console.Write("Enter a Valid .Gif file path") gifFile = Console.ReadLine

If Dir(gifFile) = "" Then Console.Write("Invalid File Path") Exit Sub End If

o = New FileStream(gifFile, FileMode.Open, FileAccess.Read, FileShare.Read) r = New StreamReader(o)

Try

Dim FileByteArray(o.Length - 1) As Byte o.Read(FileByteArray, 0, o.Length)

Dim Con As New _ System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.3.51;Persist Security Info=False;Data

Source=Test.mdb")

Dim Sql As String = "INSERT INTO Images (Pic,FileSize) VALUES (?,?)" Dim Cmd As New System.Data.OleDb.OleDbCommand(Sql, Con) Cmd.Parameters.Add("@Pic", System.Data.OleDb.OleDbType.Binary, o.Length).Value = FileByteArray Cmd.Parameters.Add("@FileSize", System.Data.OleDb.OleDbType.VarChar, 100).Value = o.Length

Con.Open() Cmd.ExecuteNonQuery() Con.Close() Catch ex As Exception Console.Write(ex.ToString)

End Try End Sub End Class

A file will be inserted in the Database each time the code is executed.

Anda mungkin juga menyukai