Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C# Bible - Jeff Ferguson, Brian Patterson, Jason Beres

.pdf
Скачиваний:
64
Добавлен:
24.05.2014
Размер:
4.21 Mб
Скачать

//Execute SQL Command selectCommand.ExecuteNonQuery();

//Report results

string contactName = selectCommand.Parameters["@ContactName_2"].Value.ToString();

string contactTitle = selectCommand.Parameters["@ContactTitle_3"].Value.ToString();

Console.WriteLine("Contact name is {0}, title is {1}.", contactName, contactTitle);

}

catch (Exception e)

{

Console.WriteLine("****** Caught an exception:\n{0}", e.Message);

}

finally

{

databaseConnection.Close();

}

}

Now, look at the generic data-reading methods. The first one uses an OleDbDataReader object. The Command object has an ExecuteReader() method, which returns an OleDbDataReader object. You can then use the Read() method to go through the content of the DataReader. Read() returns True when data is found during the read, and False otherwise. Listing 23-8 shows how this is done. Note that this example uses a SQL statement to access a stored procedure only to demonstrate an alternate way of calling a stored procedure. This is done just for educational purposes, as it is more efficient to call a stored procedure in the way demonstrated in Listing 23-7.

Listing 23-8: Retrieving a Single Record Through a DataReader

static void TestSelectWithDataReader(string customerID)

{

//Set SQL statement strings, assuming customerID doesn't contain any embedded quotes

string strSQLSelect = "EXEC [pc_getCustomer_ByCustomerID] @CustomerID_1='" + customerID + "'";

//Create OleDb objects

OleDbConnection databaseConnection = new OleDbConnection(oleDbConnectionString);

OleDbCommand selectCommand = new OleDbCommand(strSQLSelect, databaseConnection);

// We are dealing with a SQL statement (i.e. NOT a Stored Proc)

selectCommand.CommandType = CommandType.Text;

try

{

// Establish database connection databaseConnection.Open();

// Execute SQL Command OleDbDataReader rowReader =

selectCommand.ExecuteReader();

// Report results

if (rowReader.Read())

{

string contactName = rowReader["ContactName"].ToString();

string contactTitle = rowReader["ContactTitle"].ToString();

Console.WriteLine("Contact name is {0}, title is {1}.", contactName, contactTitle);

}

else

{

Console.WriteLine("No rows found!");

}

}

catch (Exception e)

{

Console.WriteLine("****** Caught an exception:\n{0}", e.Message);

}

finally

{

databaseConnection.Close();

}

}

The other generic method of retrieving data is by using the versatile DataSet object. Because the DataSet object was designed to be used independently from its originating data source, there is no OleDbDataSet or SqlDataSet, just a DataSet. A DataSet is used in conjunction with a DataAdapter. A DataAdapter object is data-store specific (that is, you use OleDbDataAdaper) and contains four embedded command objects to perform operations:

InsertCommand

SelectCommand

UpdateCommand

DeleteCommand

After setting the SelectCommand object, you can use the Fill() method to fill a DataSet. The next section shows you how to use the other three commands to alter the data contained in a DataSet. A DataSet contains one or more DataTable objects. Each DataTable contains one or more DataRow objects. These DataRow objects are stored in the Rows collection of the DataSet. A DataRow object contains one or more DataColumn objects. These DataColumn objects are stored in the Columns collection of the DataRow. The Row and the Column collections are indexed both by index and by name. In effect, you can think of the DataSet object as an in-memory database. Listing 23-9 shows a sample program that retrieves a single record using a DataSet object.

Listing 23-9: Retrieving a Single Record Through a DataSet

static void TestSelectWithDataSet(string customerID)

{

// Set SQL statement strings

string strSQLSelect = "EXEC [pc_getCustomer_ByCustomerID] @CustomerID_1='" + customerID + "'";

// Create OleDb objects

OleDbConnection databaseConnection = new OleDbConnection(oleDbConnectionString);

OleDbCommand selectCommand = new OleDbCommand(strSQLSelect, databaseConnection);

OleDbDataAdapter dsCmd = new OleDbDataAdapter(); DataSet resultDataSet = new DataSet();

// We are dealing with a SQL statement (i.e. NOT a Stored Proc)

selectCommand.CommandType = CommandType.Text;

try

{

//Establish database connection databaseConnection.Open();

//Execute SQL Command dsCmd.SelectCommand = selectCommand;

int numRows = dsCmd.Fill(resultDataSet, "Customers");

//Report results

if (numRows > 0)

{

string contactName = resultDataSet.Tables["Customers"].Rows[0]["ContactName"].ToString();

string contactTitle = resultDataSet.Tables["Customers"].Rows[0]["ContactTitle"].ToString();

Console.WriteLine("Contact name is {0}, title is {1}.", contactName, contactTitle);

}

else

{

Console.WriteLine("No rows found!");

}

}

catch (Exception e)

{

Console.WriteLine("****** Caught an exception:\n{0}", e.Message);

}

finally

{

databaseConnection.Close();

}

}

Data operations that affect single-row entities

This section looks at the InsertCommand, UpdateCommand, and DeleteCommand properties of the DataAdapter object. For each of these commands, you can either programmatically set

the command or have the command auto-generated. Programmatically setting the command usually results in better performance because there is less overhead.

Insert operations affecting single-row entities

The code in Listing 23-10 uses a common idiom that comes in handy when auto-generating Insert statements. An empty DataSet is fetched through a SelectCommand. The only purpose of this Fill() call is to retrieve the structure of the rows you want to manipulate. This is more flexible than programmatically defining this structure.

Listing 23-10: Adding a Single Record Through an Auto-Generated InsertCommand

static void TestAutoInsertWithDataSet(string customerID)

{

//Set SQL statement strings, we only need the meta-data so it doesn't matter that

//no records are matching this CustomerID.

string strSQLSelect = "EXEC [pc_getCustomer_ByCustomerID] @CustomerID_1='???'";

// Create OleDb objects

OleDbConnection databaseConnection = new OleDbConnection(oleDbConnectionString);

OleDbCommand selectCommand = new OleDbCommand(strSQLSelect, databaseConnection);

OleDbDataAdapter dsCmd = new OleDbDataAdapter();

//The following line is key to auto-generating statements!!!

OleDbCommandBuilder custCB = new OleDbCommandBuilder(dsCmd);

DataSet resultDataSet = new DataSet();

//We are dealing with a SQL statement (i.e. NOT a Stored

Proc)

selectCommand.CommandType = CommandType.Text;

try

{

//Establish database connection databaseConnection.Open();

//Execute SQL Command dsCmd.SelectCommand = selectCommand;

//This retrieves the structure of the Customers table int numRows = dsCmd.Fill(resultDataSet, "Customers");

//Create a new Row

DataRow workRow = resultDataSet.Tables["Customers"].NewRow();

// Fill in workrow data

 

// 1

 

workRow["CustomerID"] = customerID;

 

// 2

workRow["CompanyName"] = "Hungry Coyote Export Store";

workRow["ContactName"] = "Yoshi Latimer";

 

// 3

// 4

workRow["ContactTitle"] = "Sales Representative";

 

workRow["Address"] = "City Center Plaza 516 Main St.";

// 5

workRow["City"] = "Elgin";

// 6

 

 

workRow["Region"] = "OR";

// 7

8

 

workRow["PostalCode"] = "97827";

//

 

workRow["Country"] = "USA";

// 9

workRow["Phone"] = "(503) 555-6874";

// 10

workRow["Fax"] = "(503) 555-2376";

// 11

resultDataSet.Tables["Customers"].Rows.Add(workRow);

// Reconcile changes with the data source dsCmd.Update(resultDataSet, "Customers");

// Report results Console.WriteLine("Inserted 1 row.");

}

catch (Exception e)

{

Console.WriteLine("****** Caught an exception:\n{0}", e.Message);

}

finally

{

databaseConnection.Close();

}

}

The secret to auto-generating DataAdapter commands is creating a CommandBuilder object using the DataAdapter as an argument in the constructor, as shown in the following lines:

// The following line is key to auto-generating statements!!! OleDbCommandBuilder custCB = new OleDbCommandBuilder(dsCmd);

Without these lines, the subsequent Update() statement fails because the InsertCommand cannot be auto-generated. The same requirement exists for auto-generated UpdateCommand and DeleteCommand operations.

Listing 23-10 shows the complete procedure in action. After retrieving the structure of the Customers table using a stored procedure (shown in Listing 23-11), a new row is created through a call to the NewRow() method. A value is then set for each column of the new row. Then, the newly filled in row is added to the Rows collection through a call to the AddRow() method. Finally, this change is propagated to the originated data source through a call to the Update() method of the DataAdapter.

Listing 23-11: A Stored Procedure to Retrieve the Structure of the Customers Table

USE [Northwind] GO

CREATE PROCEDURE [pc_getCustomer_ByCustomerID] (@CustomerID_1 [nchar](5))

AS SELECT

[CustomerID],

[CompanyName],

[ContactName],

[ContactTitle],

[Address],

[City],

[Region],

[PostalCode],

[Country],

[Phone],

[Fax]

FROM [Northwind].[dbo].[Customers] WHERE

[CustomerID] = @CustomerID_1

You need to programmatically define a command to do the insert. You already learned how to do this with a parameterized stored procedure (one of the most efficient ways to perform data operations, by the way) in Listing 23-5. After you have defined the command and its parameters, all you need to do is set the InsertCommand of the DataAdapter, as shown in Listing 23-12. The remainder of the code (creating a new row, setting the column values, adding the new row, and updating the data source) is identical to the code used when using an auto-generated InsertCommand. Because you use a similar approach to manually create a command for the UpdateCommand and the DeleteCommand, the following section shows only how to use auto-generated commands.

Listing 23-12: Adding a Single Record Through an InsertCommand

static void TestDataSetInsertCommand(string customerID)

{

// Set SQL statement strings

string strSQLSelect = "EXEC [pc_getCustomer_ByCustomerID] @CustomerID_1='???'";

string strSQLInsert = "[pc_insCustomers]";

// Create OleDb objects

OleDbConnection databaseConnection = new OleDbConnection(oleDbConnectionString);

OleDbCommand selectCommand = new OleDbCommand(strSQLSelect, databaseConnection);

OleDbDataAdapter dsCmd = new OleDbDataAdapter(); DataSet resultDataSet = new DataSet();

// We are dealing with a SQL statement (i.e. NOT a Stored Proc)

selectCommand.CommandType = CommandType.Text;

OleDbCommand insertCommand = new OleDbCommand(strSQLInsert, databaseConnection);

insertCommand.CommandType = CommandType.StoredProcedure; insertCommand.CommandText = "[pc_insCustomers]"; insertCommand.Connection = databaseConnection;

// Add each parameter (#1 of 11) OleDbParameter param =

insertCommand.Parameters.Add("@CustomerID_1", OleDbType.VarChar, 5);

param.Direction = ParameterDirection.Input; param.SourceColumn = "CustomerID";

// Add each parameter (#2 of 11)

param = insertCommand.Parameters.Add("@CompanyName_2", OleDbType.VarChar, 40);

param.Direction = ParameterDirection.Input; param.SourceColumn = "CompanyName";

//Add each parameter 3-10

//Etc.

//Add each parameter (#11 of 11)

param = insertCommand.Parameters.Add("@Fax_11", OleDbType.VarChar, 24);

param.Direction = ParameterDirection.Input; param.SourceColumn = "Fax";

try

{

//Establish database connection databaseConnection.Open();

//Execute SQL Command dsCmd.SelectCommand = selectCommand; dsCmd.InsertCommand = insertCommand;

int numRows = dsCmd.Fill(resultDataSet, "Customers");

// Create a new Row DataRow workRow =

resultDataSet.Tables["Customers"].NewRow();

 

 

// Fill in workrow data

// 1

 

workRow["CustomerID"] = customerID;

// 2

workRow["CompanyName"] = "Hungry Coyote Export Store";

workRow["ContactName"] = "Yoshi Latimer";

// 3

// 4

workRow["ContactTitle"] = "Sales Representative";

workRow["Address"] = "City Center Plaza 516 Main St.";

// 5

workRow["City"] = "Elgin";

// 6

 

workRow["Region"] = "OR";

// 7

 

workRow["PostalCode"] = "97827";

// 8

 

workRow["Country"] = "USA";

// 9

 

workRow["Phone"] = "(503) 555-6874";

// 10

 

workRow["Fax"] = "(503) 555-2376";

// 11

 

resultDataSet.Tables["Customers"].Rows.Add(workRow);

//Reconcile changes with the data source dsCmd.Update(resultDataSet, "Customers");

//Report results Console.WriteLine("Inserted 1 row.");

}

catch (Exception e)

{

Console.WriteLine("****** Caught an exception:\n{0}", e.Message);

}

finally

{

databaseConnection.Close();

}

}

Update operations affecting single-row entities

For update operations performed through a DataSet, you obviously first need to retrieve the row you want to modify. Therefore, there is no need for the trick shown for the Insert statement. After retrieving a DataSet, you can simply update a column of a specific row. You can then call the Update() method of the DataAdapter to propagate the changes to the data source. By now, the content of Listing 23-13 will look very familiar. As pointed out in the previous section, not using auto-generated statements simply means that you need to manually create a command to handle the Update statement.

Listing 23-13: Updating a Single Record Through an Auto-Generated UpdateCommand

static void TestAutoUpdateWithDataSet(string customerID)

{

// Set SQL statement strings

string strSQLSelect = "EXEC [pc_getCustomer_ByCustomerID] @CustomerID_1='" + customerID + "'";

// Create OleDb objects

OleDbConnection databaseConnection = new OleDbConnection(oleDbConnectionString);

OleDbCommand selectCommand = new OleDbCommand(strSQLSelect, databaseConnection);

OleDbDataAdapter dsCmd = new OleDbDataAdapter();

//The following line is key to auto-generating statements!!!

OleDbCommandBuilder custCB = new OleDbCommandBuilder(dsCmd);

DataSet resultDataSet = new DataSet();

//We are dealing with a SQL statement (i.e. NOT a Stored

Proc)

selectCommand.CommandType = CommandType.Text;

try

{

//Establish database connection databaseConnection.Open();

//Execute SQL Command dsCmd.SelectCommand = selectCommand;

int numRows = dsCmd.Fill(resultDataSet, "Customers");

//Report results

if (numRows > 0)

{

resultDataSet.Tables["Customers"].Rows[0]["ContactTitle"] = "Sr. Sales Representative";

// Reconcile changes with the data source dsCmd.Update(resultDataSet, "Customers");

Console.WriteLine("1 row updated!");

}

else

{

Console.WriteLine("No rows found!");

}

}

catch (Exception e)

{

Console.WriteLine("****** Caught an exception:\n{0}", e.Message);

}

finally

{

databaseConnection.Close();

}

}

Delete operations affecting single-row entities

Of course, not all operations affecting single-row entities need to be performed through a DataSet. You can also use a stored procedure or a SQL statement. Listing 23-14 shows how to use a SQL statement to delete a single row in a table.

Listing 23-14: Deleting a Single Record Through a SQL Statement

static void TestDeleteStatement(string customerID)

{

// Set SQL statement strings

string strSQLDelete = "DELETE FROM Customers WHERE CustomerID = '" + customerID + "'";

// Create OleDb objects

OleDbConnection databaseConnection = new OleDbConnection(oleDbConnectionString);

OleDbCommand deleteCommand = new OleDbCommand(strSQLDelete, databaseConnection);

// We are dealing with a SQL statement (i.e. NOT a Stored Proc)

deleteCommand.CommandType = CommandType.Text;

try

{

//Establish database connection databaseConnection.Open();

//Execute SQL Command

int numRows = deleteCommand.ExecuteNonQuery();

// Report results Console.WriteLine("Deleted {0} row(s).",

numRows.ToString());

}

catch (Exception e)

{

Console.WriteLine("****** Caught an exception:\n{0}", e.Message);

}

finally

{

databaseConnection.Close();

}

}

Listing 23-15 finishes coverage of auto-generated commands by showing you how to delete a single row using this approach. After filling a DataSet, you can remove a row with a Delete() call. As always, an Update() call is needed to persist this change to the data source.

Listing 23-15: Deleting a Single Record Through an Auto-Generated DeleteCommand

static void TestAutoDeleteWithDataSet(string customerID)

{

// Set SQL statement strings

string strSQLSelect = "EXEC [pc_getCustomer_ByCustomerID] @CustomerID_1='" + customerID + "'";

// Create OleDb objects

OleDbConnection databaseConnection = new OleDbConnection(oleDbConnectionString);

OleDbCommand selectCommand = new OleDbCommand(strSQLSelect, databaseConnection);

OleDbDataAdapter dsCmd = new OleDbDataAdapter();

//The following line is key to auto-generating statements!!!

OleDbCommandBuilder custCB = new OleDbCommandBuilder(dsCmd);

DataSet resultDataSet = new DataSet();

//We are dealing with a SQL statement (i.e. NOT a Stored

Proc)

selectCommand.CommandType = CommandType.Text;

try

{

//Establish database connection databaseConnection.Open();

//Execute SQL Command dsCmd.SelectCommand = selectCommand;

int numRows = dsCmd.Fill(resultDataSet, "Customers");

//Report results

if (numRows > 0)

{

resultDataSet.Tables["Customers"].Rows[0].Delete();

// Reconcile changes with the data source dsCmd.Update(resultDataSet, "Customers");

Console.WriteLine("1 row deleted!");

}

else

{

Console.WriteLine("No rows found!");

}

}

catch (Exception e)

{

Console.WriteLine("****** Caught an exception:\n{0}", e.Message);

}

finally

Соседние файлы в предмете Программирование