Cover | Table of Contents | Colophon
Connection
Command
Connection
Command
Button.Click OdbcDataAdapter and uses it to fill a
DataTable with the Category table from the
Northwind sample database. The default view of the table is bound to
a data grid on the form.// Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Data;
using System.Data.Odbc;
// . . .
private void connectButton_Click(object sender, System.EventArgs e)
{
// Create the DataAdapter.
String sqlSelect = "SELECT CategoryID, CategoryName, Description " +
"FROM Categories";
OdbcDataAdapter da = new OdbcDataAdapter(sqlSelect,
ConfigurationSettings.AppSettings["Odbc_ConnectString"]);
// Create the table, fill it, and bind the default view to the grid.
DataTable dt = new DataTable( );
da.Fill(dt);
dataGrid.DataSource = dt.DefaultView;
}
OdbcConnection object. The ODBC driver
connection string is specified using the
ConnectionString property. It includes settings
needed to establish the connection to the data source. The connection
string format closely matches the ODBC connection string format.
Additionally, you can specify an ODBC data source name (DSN) or file
DSN by setting the ConnectionString attribute to
"DSN=myDSN" or
"FileDSN=myFileDSN". For more information
about specifying ODBC connection strings, see the topic
"SQLDriverConnect" in the
ODBC Programmer's ReferenceForm.Load OleDbDataAdapter that uses the Jet OLE
DB provider to access an Excel workbook. Custom insert and update
logic is created for the DataAdapter. A
DataTable is filled from the first worksheet,
Sheet1, in the Excel workbook and the default view of the table is
bound to a data grid on the form.Button.Click DataAdapter created in the
Form.Load event handler to update the Excel
workbook with the programmatic changes.// Namespaces, Variables, and Constants
using System;
using System.Configuration;
using System.Data;
private OleDbDataAdapter da;
private DataTable dt;
// . . .
private void ExcelForm_Load(object sender, System.EventArgs e)
{
// Create the DataAdapter.
da = new OleDbDataAdapter("SELECT * FROM [Sheet1$]",
ConfigurationSettings.AppSettings["Excel_0115_ConnectString"]);
// Create the insert command.
String insertSql = "INSERT INTO [Sheet1$] " +
"(CategoryID, CategoryName, Description) " +
"VALUES (?, ?, ?)";
da.InsertCommand =
new OleDbCommand(insertSql, da.SelectCommand.Connection);
da.InsertCommand.Parameters.Add("@CategoryID", OleDbType.Integer, 0,
"CategoryID");
da.InsertCommand.Parameters.Add("@CategoryName", OleDbType.Char, 15,
"CategoryName");
da.InsertCommand.Parameters.Add("@Description", OleDbType.VarChar, 100,
"Description");
// Create the update command.
String updateSql = "UPDATE [Sheet1$] " +
"SET CategoryName=?, Description=? " +
"WHERE CategoryID=?";
da.UpdateCommand =
new OleDbCommand(updateSql, da.SelectCommand.Connection);
da.UpdateCommand.Parameters.Add("@CategoryName", OleDbType.Char, 15,
"CategoryName");
da.UpdateCommand.Parameters.Add("@Description", OleDbType.VarChar, 100,
"Description");
da.UpdateCommand.Parameters.Add("@CategoryID", OleDbType.Integer, 0,
"CategoryID");
// Fill the table from the Excel spreadsheet.
dt = new DataTable( );
da.Fill(dt);
// Define the primary key.
dt.PrimaryKey = new DataColumn[] {dt.Columns[0]};
// Records can only be inserted using this technique.
dt.DefaultView.AllowDelete = false;
dt.DefaultView.AllowEdit = true;
dt.DefaultView.AllowNew = true;
// Bind the default view of the table to the grid.
dataGrid.DataSource = dt.DefaultView;
}
private void updateButton_Click(object sender, System.EventArgs e)
{
da.Update(dt);
}Jet OLEDB:Database
Password attribute in the connection string to
specify the password.Button.Click OleDbConnection object.// Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Text;
using System.Data;
using System.Data.OleDb;
// . . .
private void connectButton_Click(object sender, System.EventArgs e)
{
StringBuilder result = new StringBuilder( );
// Build the connections string incorporating the password.
String connectionString =
ConfigurationSettings.AppSettings["MsAccess_Secure_ConnectString"]+
"Jet OLEDB:Database Password=" + passwordTextBox.Text + ";";
result.Append("ConnectionString: " + Environment.NewLine +
connectionString + Environment.NewLine + Environment.NewLine);
OleDbConnection conn = new OleDbConnection(connectionString);
try
{
conn.Open( );
// Retrieve some database information.
result.Append(
"Connection State: " + conn.State + Environment.NewLine +
"OLE DB Provider: " + conn.Provider +
Environment.NewLine +
"Server Version: " + conn.ServerVersion +
Environment.NewLine);
conn.Close( );
result.Append("Connection State: " + conn.State);
}
catch(System.Data.OleDb.OleDbException ex)
{
conn.Close( );
result.Append("ERROR: " + ex.Message);
}
resultTextBox.Text = result.ToString( );
}
Jet OLEDB:System Database attribute in the
connection string to specify the path and filename of the workgroup
information file or system database.Button.ClickOleDbConnection object.// Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Text;
using System.Data.OleDb;
// . . .
private void connectButton_Click(object sender, System.EventArgs e)
{
StringBuilder result = new StringBuilder( );
// Build the connection string with security information.
String connectionString =
ConfigurationSettings.AppSettings["MsAccess_ConnectString"] +
@"Jet OLEDB:System database=" +
ConfigurationSettings.AppSettings["MsAccess_SecureMdw_Filename"] +
";" + "User ID=" + userIdTextBox.Text + ";" +
"Password=" + passwordTextBox.Text + ";" +
Environment.NewLine + Environment.NewLine;
result.Append(connectionString);
// Create the connection.
OleDbConnection conn = new OleDbConnection(connectionString);
try
{
// Attempt to open the connection.
conn.Open( );
result.Append(
"Connection State: " + conn.State + Environment.NewLine +
"OLE DB Provider: " + conn.Provider +
Environment.NewLine +
"Server Version: " + conn.ServerVersion +
Environment.NewLine);
conn.Close( );
result.Append("Connection State: " + conn.State +
Environment.NewLine);
}
catch(System.Data.OleDb.OleDbException ex)
{
result.Append("ERROR: " + ex.Message);
}
resultTextBox.Text = result.ToString( );
}web.config file for a given
ASP.NET application so that ASP.NET impersonates an account on the
Microsoft Access computer with the required access permissions to the
Access database. For example:<identity impersonate="true" userName="domain\username"
password="myPassword" />
Network Address
and Network Library attributes
of the connection string.Button.ClickSqlConnection object.// Namespaces, variables, and constants
using System;
using System.Data.SqlClient;
// . . .
private void connectButton_Click(object sender, System.EventArgs e)
{
String connString =
"Network Library=dbmssocn;Network Address=127.0.0.1
;" +
"Integrated security=SSPI;Initial Catalog=Northwind";
SqlConnection conn = new SqlConnection(connString);
conn.Open( );
// Return some information about the server.
resultTextBox.Text =
"ConnectionState = " + conn.State + Environment.NewLine +
"DataSource = " + conn.DataSource + Environment.NewLine +
"ServerVersion = " + conn.ServerVersion + Environment.NewLine;
conn.Close( );
resultTextBox.Text += "ConnectionState = " + conn.State;
}
Button.Click SqlConnection object.// Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Windows.Forms;
using System.Text;
using System.Data.SqlClient;
// . . .
private void connectButton_Click(object sender, System.EventArgs e)
{
StringBuilder result = new StringBuilder( );
SqlConnection conn = new SqlConnection(
ConfigurationSettings.AppSettings["Sql_Msde_ConnectString"]);
try
{
conn.Open( );
// Return some information about the server.
result.Append(
"ConnectionState = " + conn.State + Environment.NewLine +
"DataSource = " + conn.DataSource + Environment.NewLine +
"ConnectionState = " + conn.State + Environment.NewLine +
"ServerVersion=" + conn.ServerVersion +
Environment.NewLine);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
conn.Close( );
}
result.Append("ConnectionState = " + conn.State);
resultTextBox.Text = result.ToString( );
}
<computerName>\<instanceName>. This
format is used in the connection string to specify the
Data Source attribute for a
named instance.Integrated Windows
Authentication is enabled and
Anonymous Access is disabled.<authentication mode="Windows" /> <identity impersonate="true" />
Integrated Security=SSPI
attribute-and-value pair instead of the User
ID and Password attributes in
the connection string. The older attribute-and-value pair
Trusted_Connection=Yes is also supported.ASPNET on IIS. The account has limited permissions
and is local to the IIS computer and therefore not recognized as a
user on remote computers. To overcome this limitation when SQL Server
is not on the same computer as IIS, run the web application in the
context of a domain user recognized on both IIS and SQL Server
computers.Button.Click OracleConnection object.Button.ClickOleDbConnection object.// Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Data.OleDb;
using System.Data.OracleClient;
// . . .
private void oracleProviderButton_Click(object sender, System.EventArgs e)
{
// Connect to Oracle using Microsoft Oracle .NET data provider.
OracleConnection conn = new OracleConnection(
ConfigurationSettings.AppSettings["Oracle_Scott_ConnectString"]);
resultTextBox.Text = "Connection with ORACLE Provider" +
Environment.NewLine;
try
{
conn.Open( );
resultTextBox.Text += "ConnectionState = " + conn.State +
Environment.NewLine +
"DataSource = " + conn.DataSource +
Environment.NewLine +
"ServerVersion = " + conn.ServerVersion +
Environment.NewLine;
}
catch(OracleException ex)
{
resultTextBox.Text += "ERROR: " + ex.Message;
}
finally
{
conn.Close( );
resultTextBox.Text += "ConnectionState = " + conn.State;
}
}
private void oleDbButton_Click(object sender, System.EventArgs e)
{
// Connect to Oracle using OLE DB .NET data provider.
OleDbConnection conn = new OleDbConnection(
ConfigurationSettings.AppSettings["OleDb_Oracle_ConnectString"]);
resultTextBox.Text = "Connection with OLE DB Provider" +
Environment.NewLine;
try
{
conn.Open( );
resultTextBox.Text += "ConnectionState = " + conn.State +
Environment.NewLine +
"DataSource = " + conn.DataSource +
Environment.NewLine +
"ServerVersion = " + conn.ServerVersion +
Environment.NewLine;
}
catch(OleDbException ex)
{
resultTextBox.Text += "ERROR: " + ex.Message;
}
finally
{
conn.Close( );
resultTextBox.Text += "ConnectionState = " + conn.State +
Environment.NewLine;
}
}Form.LoadButton.ClickDataAdapter is used
to fill a table with the Subject and
Content of each message in the
Inbox. The default view of the table is
bound to a data grid on the form.// Namespaces, variables, and constants
using System;
using System.Windows.Forms;
using System.Data;
using System.Data.OleDb;
// . . .
private void ConnectExchangeDataForm_Load(object sender,
System.EventArgs e)
{
mailboxNameTextBox.Text = "Personal Folders";
profileTextBox.Text = "Outlook";
}
private void connectButton_Click(object sender, System.EventArgs e)
{
String sqlText = "SELECT Subject, Contents FROM Inbox";
// Build the connection string.
String connectionString="Provider=Microsoft.Jet.OLEDB.4.0;" +
"Outlook 9.0;" +
"MAPILEVEL=" + mailboxNameTextBox.Text + "|;" +
"PROFILE=" + profileTextBox.Text + ";" +
"TABLETYPE=0;" +
"DATABASE=" + System.IO.Path.GetTempPath( );
// Create the DataAdapter.
OleDbDataAdapter da = new OleDbDataAdapter(sqlText, connectionString);
// Create and fill the table.
DataTable dt = new DataTable("Inbox");
try
{
da.Fill(dt);
dataGrid.DataSource = dt.DefaultView;
}
catch(Exception ex)
{
MessageBox.Show("ERROR: " + ex.Message);
return;
}
}
Microsoft.Jet.OLEDB.4.0;Outlook 9.0;MAPILEVEL=Personal Folders|;
PROFILE=Outlook;TABLETYPE=0;DATABASE=c:\temp;Connection and
DataReader) to create provider-independent code
that can be used with provider-specific code to access unique
functionality.GetData( )
Connection and
DataAdapter arguments as generic
IDbConnection and
IDbDataAdapter interface types. The interfaces are
used to fill a DataSet from the Customers table in
Northwind. The default view of the Customers
DataTable is bound to the data grid on the form.Connection for the
IDbConnection is identified and provider-specific
logic executed.Button.Click SqlConnection and a
SqlDataAdapter object and passes them as arguments
into the provider-independent GetData( ) method.Button.ClickOleDbConnection and an
OleDbDataAdapter object and passes them as
arguments into the provider-independent GetData( )
method.// Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Windows.Forms;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.OleDb;
// . . .
private void GetData(IDbConnection conn, IDbDataAdapter da)
{
// Create the command and assign it to the IDbDataAdapter interface.
IDbCommand cmd = conn.CreateCommand( );
cmd.CommandText = "SELECT * FROM Customers";
da.SelectCommand = cmd;
// Add a table mapping.
da.TableMappings.Add("Table", "Customers");
dataGrid.DataSource = null;
// Fill the DataSet.
DataSet ds = new DataSet( );
da.Fill(ds);
// Bind the default view for the Customer table to the grid.
dataGrid.DataSource = ds.Tables["Customers"].DefaultView;
// Identify provider-specific connection type and process appropriately.
if (conn is SqlConnection)
{
MessageBox.Show("Specific processing for SQL data provider.");
}
else if(conn is OleDbConnection)
{
MessageBox.Show("Specific processing for OLE DB data provider.");
}
}
private void sqlButton_Click(object sender, System.EventArgs e)
{
// Create a SQL Connection and DataAdapter.
SqlConnection conn = new SqlConnection(
ConfigurationSettings.AppSettings["Sql_ConnectString"]);
SqlDataAdapter da = new SqlDataAdapter( );
dataGrid.CaptionText = "SQL .NET Provider";
// Call provider-independent function to retrieve data.
GetData(conn, da);
}
private void oleDbButton_Click(object sender, System.EventArgs e)
{
// Create a OLE DB Connection and DataAdapter.
OleDbConnection conn = new OleDbConnection(
ConfigurationSettings.AppSettings["OleDb_ConnectString"]);
OleDbDataAdapter da = new OleDbDataAdapter( );
dataGrid.CaptionText = "OLE DB .NET Provider";
// Call provider-independent function to retrieve data.
GetData(conn, da);
}Server Explorer window in the
Visual Studio .NET IDE.adodb from the .NET tab in Visual Studio
.NET's Add Reference Dialog. You'll
also need a reference to the Microsoft OLE DB Service Component 1.0
Type Library from the COM tab in Visual Studio
.NET's Add Reference Dialog.Button.Click // Namespaces, variables, and constants
using System;
// . . .
private void dataLinkDialogButton_Click(object sender, System.EventArgs e)
{
ADODB.Connection conn = new ADODB.Connection( );
object oConn = (object) conn;
MSDASC.DataLinks dlg = new MSDASC.DataLinks( );
dlg.PromptEdit(ref oConn);
connectionStringTextBox.Text = conn.ConnectionString;
}
Audit Login and
Audit Logout events appear
beneath the Security Audit node. Remove all other events from the
list. Click the Run button to start the trace.Audit Login events when
connections are established and Audit
Logout events when connections are closed.Connection is closed or disposed.
The connection pool manager removes expired connections and
connections that have had their connection with the server severed
from the pool.Connection object should be closed as soon as
it is no longer needed so that it is added to or returned to the
connection pool. This is done by calling either the Close(
) or Dispose( ) method of the
Connection. Connections that are not explicitly
closed might not be added to or returned to the connection pool.Form.LoadConnection, attaches an event handler to
its StateChange event, and sets default properties
for controls on the form that are used to specify connection
properties. The UpdateConnection( ) method is
called to dynamically construct a connection string from the
specified properties.UpdateConnectionString( )Button.ClickConnection that is based on the
connection string constructed in the UpdateConnectionString(
) method.Button.ClickConnection.StateChange// Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
private SqlConnection conn;
// . . .
private void ConnectionPoolingOptionsForm_Load(object sender,
System.EventArgs e)
{
conn = new SqlConnection( );
conn.StateChange += new StateChangeEventHandler(conn_StateChange);
connectionStringTextBox.Text =
ConfigurationSettings.AppSettings["Sql_ConnectString"];
connectTimeoutTextBox.Text = "15";
connectLifetimeTextBox.Text = "0";
minPoolSizeTextBox.Text = "0";
maxPoolSizeTextBox.Text = "100";
poolCheckBox.Checked = true;
UpdateConnectionString( );
}
private void UpdateConnectionString( )
{
connectionStringTextBox.Text =
ConfigurationSettings.AppSettings["Sql_ConnectString"] +
"Connection Timeout = " + connectTimeoutTextBox.Text + ";" +
"Connection Lifetime = " + connectLifetimeTextBox.Text + ";" +
"Min Pool Size = " + minPoolSizeTextBox.Text + ";" +
"Max Pool Size = " + maxPoolSizeTextBox.Text + ";" +
"Pooling = " + poolCheckBox.Checked.ToString( );
}
private void openButton_Click(object sender, System.EventArgs e)
{
try
{
conn.ConnectionString = connectionStringTextBox.Text;
conn.Open( );
}
catch(SqlException ex)
{
MessageBox.Show("ERROR: " + ex.ToString( ), "Open Connection",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch(InvalidOperationException ex)
{
MessageBox.Show("ERROR: " + ex.ToString( ), "Open Connection",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void closeButton_Click(object sender, System.EventArgs e)
{
conn.Close( );
}
private void conn_StateChange(object sender, StateChangeEventArgs e)
{
connectionStateTextBox.Text =
"Connection.StateChange event occurred" +
Environment.NewLine +
"OriginalState = " + e.OriginalState.ToString( ) +
Environment.NewLine +
"CurrentState = " + e.CurrentState.ToString( );
}ChangeDatabase(
)
method to change the database for a
connection.Connection to the
Northwind database using the SQL Server .NET data provider. The
connection is changed to use the pubs database. Finally the
connection is closed. The Database property of the
SqlConnection object is displayed throughout the
sample for the different connection states.// Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Text;
using System.Data;
using System.Data.SqlClient;
// . . .
StringBuilder result = new StringBuilder( );
// Create the connection accessing Northwind database.
SqlConnection conn = new SqlConnection(
ConfigurationSettings.AppSettings["Sql_ConnectString"]);
result.Append("Connection String:" + Environment.NewLine);
result.Append(conn.ConnectionString + Environment.NewLine + Environment.NewLine);
// Open the connection.
conn.Open( );
result.Append("Connection.State: " + conn.State + Environment.NewLine);
result.Append("Database: " + conn.Database + Environment.NewLine);
// Change the database to pubs.
conn.ChangeDatabase("pubs");
result.Append("Database: " + conn.Database + Environment.NewLine);
// Close the connection.
conn.Close( );
result.Append("Connection.State: " + conn.State + Environment.NewLine);
result.Append("Database: " + conn.Database);
resultTextBox.Text = result.ToString( );
ChangeDatabase( ) method is defined in the
IDbConnection interface that represents a
connection to a data source and is implemented by .NET data providers
for relational databases including those for SQL Server, Oracle, and
OLE DB. The ChangeDatabase( ) method is used to
change the current database for an open connection. It takes a single
parameter that specifies the name of the database to use in place of
the current database. The name of the database must be valid or an
ArgumentException will be raised. If the
connection is not open when the method is called, an
OleDbDataAdapter that
uses the Jet OLE DB provider to load the contents of the text file
Categories.txt, shown in Example 1-13, into a DataTable and
displays the contents in a data grid on the form."CategoryID","CategoryName","Description" 1,"Beverages","Soft drinks, coffees, teas, beers, and ales" 2,"Condiments","Sweet and savory sauces, relishes, spreads, and seasonings" 3,"Confections","Desserts, candies, and sweet breads" 4,"Dairy Products","Cheeses" 5,"Grains/Cereals","Breads, crackers, pasta, and cereal" 6,"Meat/Poultry","Prepared meats" 7,"Produce","Dried fruit and bean curd" 8,"Seafood","Seaweed and fish"
// Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Windows.Forms;
using System.Data;
using System.Data.OleDb;
// . . .
// Create the data adapter to retrieve all rows from text file.
OleDbDataAdapter da =
new OleDbDataAdapter("SELECT * FROM [Categories.txt]",
ConfigurationSettings.AppSettings["TextFile_0119_ConnectString"]);
// Create and fill the table.
DataTable dt = new DataTable("Categories");
da.Fill(dt);
// Bind the default view of the table to the grid.
categoriesDataGrid.DataSource = dt.DefaultView;
Extended
Properties attribute of the connection. Text files
are supported with the text source database type
as shown in the following example:Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\MyTextFileDirectory;
Extended Properties="text;HDR=yes;FMT=Delimited";
Extended Properties attribute can, in addition
to the ISAM version property, specify whether or not tables include
headers as field names in the first row of a range using an
DataSet is a disconnected, in-memory
relational database that provides sophisticated navigational
capabilities. It acts as a container for other objects including
DataTable, DataColumn,
DataRow, and DataRelation. The
DataAdapter works with the
DataSet to update the data source with changes
made offline to the DataSet. You can also data
bind a DataSet to a variety of Windows Forms and
Web Forms controls, in particular, any control that supports the
IList interface. The DataSet
maintains both current and original versions of its data. Although
data appears to be changed, it is not permanently changed until the
AcceptChanges( ) method is called either
explicitly or implicitly to commit the changes. Recipe 2.6 shows how to access rows marked for deletion.DataReader provides forward-only, read-only
access to a result set. The DataReader offers the
best performance for accessing data by avoiding the overhead
associated with the DataSet. The
Connection object underlying a
DataReader remains open and cannot be used for any
other purpose while data is being accessed. This makes the
DataReader unsuitable for communicating data
remotely between application tiers, or interacting with the data
dynamically. If you want to discard a result set in a
DataReader before the entire result set has been
read, call the Cancel( ) method of the
DataReader before calling the Close(
) method. This discards the results on the server so they
are not transmitted to the client. Simply calling Close(
) causes the remaining results to be pulled to the client
to empty the stream. Since the DataReader reads a
result set stream directly from a connection, there is no way to know
the number of records in a DataReader. Recipe 2.7 demonstrates techniques that simulate a
record count for a DataReader and discusses
limitations of the techniques.DataSet and
DataReader object schemas programmatically or
infer them from a database schema. Retrieving schema information from
the database has its limitations. For example, data relations cannot
be created in a DataSetDataSet is a disconnected, in-memory
relational database that provides sophisticated navigational
capabilities. It acts as a container for other objects including
DataTable, DataColumn,
DataRow, and DataRelation. The
DataAdapter works with the
DataSet to update the data source with changes
made offline to the DataSet. You can also data
bind a DataSet to a variety of Windows Forms and
Web Forms controls, in particular, any control that supports the
IList interface. The DataSet
maintains both current and original versions of its data. Although
data appears to be changed, it is not permanently changed until the
AcceptChanges( ) method is called either
explicitly or implicitly to commit the changes. Recipe 2.6 shows how to access rows marked for deletion.DataReader provides forward-only, read-only
access to a result set. The DataReader offers the
best performance for accessing data by avoiding the overhead
associated with the DataSet. The
Connection object underlying a
DataReader remains open and cannot be used for any
other purpose while data is being accessed. This makes the
DataReader unsuitable for communicating data
remotely between application tiers, or interacting with the data
dynamically. If you want to discard a result set in a
DataReader before the entire result set has been
read, call the Cancel( ) method of the
DataReader before calling the Close(
) method. This discards the results on the server so they
are not transmitted to the client. Simply calling Close(
) causes the remaining results to be pulled to the client
to empty the stream. Since the DataReader reads a
result set stream directly from a connection, there is no way to know
the number of records in a DataReader. Recipe 2.7 demonstrates techniques that simulate a
record count for a DataReader and discusses
limitations of the techniques.DataSet and
DataReader object schemas programmatically or
infer them from a database schema. Retrieving schema information from
the database has its limitations. For example, data relations cannot
be created in a DataSet from the database schema.DataSet with
parent and related child data, even if the DataSet
already has a schema that includes the relationship.DataSet.Form.LoadDataSet with
table schemas for both the Orders table and the Order Details table
from Northwind and a DataRelation object relating
these two tables. The default view of the parent table, Orders, is
bound to a data grid on the form.Button.ClickDataSet and
refreshing the data grid. DataAdapter objects are
created for both the parent and the child table. The Orders and Order
Details are then filled using data adapters in the sequence specified
and enforcing constraints during the load as specified by the user.// Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
private DataSet ds;
// . . .
private void HierarchicalDataSetForm_Load(object sender,
System.EventArgs e)
{
ds = new DataSet( );
// Get the schema for the Orders table.
DataTable parentTable = new DataTable("Orders");
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Orders",
ConfigurationSettings.AppSettings["Sql_ConnectString"]);
da.FillSchema(parentTable, SchemaType.Source);
ds.Tables.Add(parentTable);
// Get the schema for the Order Details table.
DataTable childTable = new DataTable("Order Details");
da = new SqlDataAdapter("SELECT * FROM [Order Details]",
ConfigurationSettings.AppSettings["Sql_ConnectString"]);
da.FillSchema(childTable, SchemaType.Source);
ds.Tables.Add(childTable);
// Add the relation between the tables.
DataRelation dr = new DataRelation("Order_OrderDetails_Relation",
parentTable.Columns["OrderID"], childTable.Columns["OrderID"]);
ds.Relations.Add(dr);
// Bind the default view of the Orders table with the grid.
dataGrid.DataSource = parentTable.DefaultView;
}
private void loadDataSetButton_Click(object sender, System.EventArgs e)
{
// Remove all data from the DataSet and refresh the grid.
ds.Clear( );
dataGrid.Refresh( );
// Create parent and child data adapters.
SqlDataAdapter daParent = new SqlDataAdapter("SELECT * FROM Orders",
ConfigurationSettings.AppSettings["Sql_ConnectString"]);
SqlDataAdapter daChild = new SqlDataAdapter(
"SELECT * FROM [Order Details]",
ConfigurationSettings.AppSettings["Sql_ConnectString"]);
// Enforce constraints as specified by user.
ds.EnforceConstraints = (enforceConstraintsCheckBox.Checked);
try
{
if (loadParentFirstRadioButton.Checked)
{
// Load parent data first.
daParent.Fill(ds, "Orders");
daChild.Fill(ds, "Order Details");
}
else
{
// Load child data first.
daChild.Fill(ds, "Order Details");
daParent.Fill(ds, "Orders");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
ds.EnforceConstraints = true;
}DataSet
programmatically—including adding tables, columns, primary
keys, and relations—from a schema that you have designed.DataSet programmatically, including how to build
and add tables, columns, primary key constraints, relations, and
column mappings. Use this as a template for building your own
DataSet.