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

ASP .NET Web Developer s Guide - Mesbah Ahmed, Chris Garrett

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

320 Chapter 7 • Introduction to ADO.NET: A Simple Address Book

Create a new class file in Visual Studio and add the code in Figure 7.11 (A and B) to the body of the file. Name this file CDalAddress.vb for VB.NET and

CDalAddress.cs for C#.NET.

Figure 7.11 (A and B) Implementing the Connection String Property in the Data Access Layer

Figure 7.11A C#.NET (cs\CDalAddress.cs)

using

System;

using

System.Data;

using

System.Data.SqlClient;

using

System.Data.SqlTypes;

using

System.Data.OleDb;

namespace Chapter7_cs

{

///<summary>

///

Summary

description

for

CDalAddress.

///

</summary>

 

 

 

public

class CDalAddress

 

 

{

 

 

 

 

string strConStr; string strError; SqlConnection oConn;

// OleDbConnection oConn;

public string strConnection

{

get

{

return strConStr;

}

set

{

strConStr = value; try

{

Continued

www.syngress.com

Introduction to ADO.NET: A Simple Address Book • Chapter 7

321

Figure 7.11A Continued

this.oConn = new SqlConnection(value); // oConn = new OleDbConnection(value);

}

catch (Exception e)

{

throw e;

}

}

}

}

}

Figure 7.11B VB.NET (vb\CDalAddress.vb)

Option Explicit On

Imports System

Imports System.Data

Imports System.Data.SqlClient

Imports System.Data.OleDb

Public Class CdalAddress

'// a conneciton string Private strConStr As String Private oConn As SqlConnection

'Private oConn As OleDbConnection

Public Property strConnection() As String

Get

Return strConStr

End Get

Set(ByVal Value As String)

strConStr = Value

Try

oConn = New SqlConnection(Value)

'oConn = New OleDbConnection(Value)

Continued

www.syngress.com

322 Chapter 7 • Introduction to ADO.NET: A Simple Address Book

Figure 7.11B Continued

Catch oleE As OleDbException

Throw oleE

Catch e As SqlException

Throw e

End Try

End Set

End Property

End Class

We now have a class with one property. On the set operation of the strConnection property, set the private variable strConStr to the Connection string, and then create the connection with the new operator and the type of connection we are creating. Figure 7.12 (A and B) illustrates instantiating the Connection object.

Figure 7.12 (A and B) Instantiating the Connection Object

Figure 7.12A C#.NET

//For a SQL Server only connection oConn = New SqlConnection(Value);

//For an OleDb connection

oConn = New OleDbConnection(Value);

Figure 7.12B VB.NET

'For a SQL Server only conneciton oConn = New SqlConnection(Value)

'For an OleDb connection

oConn = New OleDbConnection(Value)

The error handling is self-explanatory; basically you just bubble it back to the caller.To recap, you set a reference to the namespace, declare a variable of type SqlConnection, and then call the New operator and pass the connection string into the constructor. So, creating the connection comes down to three lines of code.

www.syngress.com

Introduction to ADO.NET: A Simple Address Book • Chapter 7

323

In our sample, we commented out the lines responsible for creating the OleDbConnection object.That and the different connection string are all it takes to switch database connections.

Browsing a Database: Exercise

Now that you are connected to the database, you can retrieve some records. Data retrieval is the most intensive thing that you will do to your database. Online Transaction Processing, or OLTP, applications are designed for inserting and updating data quickly.They are not designed for fast and efficient retrieval of multi-dimensional data. Modern Relational Database technology does a good job of satisfying most needs, but many people often find themselves needing faster access to the data than they are currently getting. Faster is better, right? One of the benefits of ASP.NET are the caching and state management features.They enable you to connect to a database, return some results, and then cache this for a specific period of time.This caching can improve performance dramatically, while reducing the amount of load on the database. It is a true win-win situation.

Our example uses two methods that return data reader objects to the calling procedure. A Data Reader is a read-only, forward-only cursor.You can bind it to a DataGrid, a DataList, a DataRepeater, etc.You can only use it once due to its for- ward-only nature.This is the workhorse for ADO.NET, and especially for data access in ASP.NET.

Another object for browsing data is the DataSet. You can think of the DataSet as an in-memory database.You can add DataTables, which are synonymous with database tables; you can create DataViews, DataRelations, and constraints.The DataSet is very useful when you are going to access the same data more than twice in a page hit or session.The thing to keep in mind is that it is not connected to the database. Once you fill the DataTable, it is disconnected from the data source.The DataTable doesn’t know anything about the database. As far as ASP.NET goes, DataTables are useful for populating drop-downs with data that doesn’t change very often, but is used many times in a single session. If you place a DataSet in a session, beware that the memory is taken up until the session times out, not just when the user leaves the site. Our example doesn’t use the DataSet, but a DataSet can be bound to the DataList in the same manner as the

DataReaders are.

Our example uses stored procedures extensively for SQL Server, and raw SQL for Access. Not all Relational databases create and consume stored procedures the same way; therefore their implementation is specific to the database. In this example,T-SQL is used to create the stored procedures in SQL Server.

www.syngress.com

324 Chapter 7 • Introduction to ADO.NET: A Simple Address Book

The first stored procedure gets all the records and orders them Last Name, First Name. Refer to Figure 7.13 for the code to create the stored procedure.

Figure 7.13 Selecting Data from the Database T-SQL

CREATE PROC usp_tblAddress_sel

AS

SELECT [AdrsID]

,[FName]

,[LName]

,[Phone]

,[EMail]

,[WebPage]

,[Age]

,[Comments]

FROM [dbo].[tblAddress]

ORDER BY [LName], [FName]

This stored procedure doesn’t take any parameters, so we have a couple of ways to call it. In Access, we would not be able to create the stored procedure, so we will just have to use the SQL Statement in place of the stored procedure name.We are going to use the simpler Text CommandType refer to Figure 7.14 (A and B).

Figure 7.14 (A and B) Selecting Data from the Database

Figure 7.14A C#.Net (cs\CDalAddress.cs)

public SqlDataReader getAll()

{

string strSQL = "EXEC usp_tblAddress_sel"; SqlCommand oCmd = new SqlCommand(strSQL, oConn);

// OleDbCommand oCmd = new OleDbCommand(strSQL, oConn); oCmd.CommandType = CommandType.Text;

try

{

if (oConn.State == ConnectionState.Closed)

{

oConn.Open();

Continued

www.syngress.com

Introduction to ADO.NET: A Simple Address Book • Chapter 7

325

Figure 7.14A Continued

}

return oCmd.ExecuteReader();

}

catch (Exception e)

{

throw e;

}

}

Figure 7.14B VB.NET (vb\CDalAddress.vb)

Public Function getAll() As SqlDataReader

'Public Function getAll() As OleDbDataReader Dim oCmd As SqlCommand

'Dim oCmd As OleDbCommand Dim strSQL As String

strSQL = "EXEC usp_tblAddress_sel" oCmd = New SqlCommand(strSQL, oConn)

'oCmd = New OleDbCommand(strSQL, oConn)

oCmd.CommandType = CommandType.Text

Try

If oConn.State = ConnectionState.Closed Then

oConn.Open()

End If

Return oCmd.ExecuteReader

Catch oErr As Exception

Throw oErr

End Try

End Function

Notice in our Try Catch block that we are checking the current state of the connection. If it is closed, then we want to open it.We can check for various states;Table 7.4 lists the available states and gives a brief description of each one. The ExecuteReader of our Command object returns a DataReader that we return to the calling function.

www.syngress.com

326 Chapter 7 • Introduction to ADO.NET: A Simple Address Book

Table 7.4 Connection States

Connection

 

State

Description

 

 

Open

Object has located and authenticated the connection, and is

 

ready for commands.

Closed

Not connection to the data source. Default state when a

 

connection object is created.

Connecting

Object is in the process of connecting.

Executing

Object is in the process of executing a command.

Fetching

Object is retrieving, or fetching data.

Broken

Can only happen after a connection is open. To recover from

 

this, a connection must be closed and the reopened.

In our earlier example, we set the SQL statement to EXEC usp_tblAddress_sel. EXEC[UTE] is a Transact SQL command to execute a stored procedure and return the result.The text immediately following it, usp_tblAddress_sel is the name of the stored procedure.This is the simplest way to execute a stored procedure.We could have also just specified the Select statement instead. For example, if we were using Access with Jet, it doesn’t support stored procedures so we would have to create the select statement and send it to the OleDbCommand object.To change the code for Access, refer to Figure 7.15.

Figure 7.15 Switch from a Stored Procedure to Embedded SQL

The line:

strSQL = "EXEC usp_tblAddress_sel";

Becomes:

strSQL = " SELECT [AdrsID]

,[FName]

,[LName]

,[Phone]

,[EMail]

,[WebPage]

,[Age]

,[Comments]

FROM [dbo].[tblAddress]

ORDER BY [LName], [FName]";

www.syngress.com

Introduction to ADO.NET: A Simple Address Book • Chapter 7

327

The results are the same.The reason we use stored procedures in SQL Server is that SQL Server can optimize the query plan and reuse it for subsequent executions.This eliminates the parsing, and compiling that takes place when we send in Embedded SQL. Refer to the sidebar entitled “Embedded SQL Statements” for an explanation of Embedded SQL. It is more flexible than the stored procedure method, but for 95 percent of database operations, dynamic SQL is not the only way to get the job done.

Developing & Deploying…

Embedded SQL Statements

Embedded SQL or Dynamic SQL is a term given to generating SQL statements at runtime and executing it against the database. For Access it is the only method. For SQL Server, Oracle, DB2, and so on, it is optional. For SQL Server the stored procedure is preferred for several reasons. SQL Server can optimize the query plan and cache it for reuse, thus saving the cost of parsing and compiling the statement every time it runs. Also, you can execute a stored procedure against a table that you do not have select access to. SQL Server does this through the ownership chain, where the owner of an object can create a table and a stored procedure. They can give you execute permission on the stored procedure, but not give you select permission on the table. Since they own both objects, SQL Server will grant the user access to the table, but only through the stored procedure that the table owner created.

The next method returns a particular row identified by the Primary key.We use the Primary key to uniquely identify a row, so it is a very reliable way of ensuring that you get exactly the row that you wanted. Figure 7.16 (A and B) contains the Transact SQL for the stored procedure.

Figure 7.16 (A and B) Selecting a Particular Record

Figure 7.16A T-SQL

CREATE PROC usp_tblAddress_sel_ByID(@AdrsID INT)

AS

SELECT [AdrsID]

Continued

www.syngress.com

328 Chapter 7 • Introduction to ADO.NET: A Simple Address Book

Figure 7.16A Continued

,[FName]

,[LName]

,[Phone]

,[EMail]

,[WebPage]

,[Age]

,[Comments]

FROM [dbo].[tblAddress]

WHERE [AdrsID] = @AdrsID

Figure 7.16B Access

SELECT [AdrsID]

,[FName]

,[LName]

,[Phone]

,[EMail]

,[WebPage]

,[Age]

,[Comments]

FROM [tblAddress]

WHERE [AdrsID] = <replace with your id>

Even though we must specify a parameter, we can still use the Text CommandType with our Command object by concatenating the variable to our command text. Figure 7.17 (A and B) contains the code listing for the getByID function of our DAL.

Figure 7.17 (A and B) GetByID Function—Use Dynamic SQL to Call a Stored Procedure

Figure 7.17A C#.NET (cs\CDalAddress.cs)

public SqlDataReader getByID(Int32 AdrsID)

{

string strSQL = strSQL = "EXEC usp_tblAddress_sel_ByID " +

Continued

www.syngress.com

Introduction to ADO.NET: A Simple Address Book • Chapter 7

329

Figure 7.17A Continued

AdrsID.ToString();

SqlCommand oCmd = new SqlCommand(strSQL, oConn); oCmd.CommandType = CommandType.Text;

try

{

if (oConn.State == ConnectionState.Closed)

{

oConn.Open();

}

return oCmd.ExecuteReader();

}

catch (Exception e)

{

throw e;

}

}

Figure 7.17B VB.NET (vb\CDalAddress.vb)

Public Function getByID(ByVal AdrsID As Int32) As SqlDataReader Dim oCmd As SqlCommand

Dim strSQL As String

strSQL = "EXEC usp_tblAddress_sel_ByID " & AdrsID oCmd = New SqlCommand(strSQL, oConn) oCmd.CommandType = CommandType.Text

Try

If oConn.State = ConnectionState.Closed Then

oConn.Open()

End If

Return oCmd.ExecuteReader

Catch oErr As Exception

Throw New Exception(oErr.ToString)

End Try

End Function

www.syngress.com