Tải bản đầy đủ (.pdf) (10 trang)

ASP.NET 4 Unleased - p 96 pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (541.58 KB, 10 trang )

ptg
924
CHAPTER 19 Building Data Access Components with ADO.NET
Creating the User-Defined Type
After you have loaded the DBMovie assembly, you can create a new user-defined type
from the assembly. Execute the following command:
CREATE TYPE dbo.DBMovie EXTERNAL NAME DBMovie.DBMovie
If you need to delete the type, you can execute the following command:
DROP TYPE DBMovie
After you have added the type, you can use it just like any other SQL Server native type.
For example, you can create a new database table with the following command:
CREATE TABLE DBMovies(Id INT IDENTITY, Movie DBMovie)
You can insert a new record into this table with the following command:
INSERT DBMovies (Movie)
VALUES (‘Star Wars,George Lucas,12.34’)
Finally, you can perform queries against the table with queries like the following:
SELECT Id, Movie FROM DBMovies WHERE Movie.BoxOfficeTotals > 13.23
SELECT MAX(Movie.BoxOfficeTotals) FROM DBMovies
SELECT Movie FROM DBMovies WHERE Movie.Director LIKE ‘g%’
I find the fact that you can execute queries like this truly amazing.
Building a Data Access Layer with a User-Defined Type
In this final section, let’s actually do something with our new user-defined type. We create
a new data access component that uses the DBMovie class and an ASP.NET page that inter-
faces with the component.
Before we can do anything with the DBMovie type, we need to add a reference to the
DBMovie.dll assembly to our application. In Visual Web Developer, select Website, Add
Reference, and browse to the DBMovie.dll. Alternatively, you can create an application
root Bin folder and copy the DBMovie.dll into the Bin folder.
Our new data access component is contained in Listing 19.37.
LISTING 19.37 App_Code\DBDataLayer.cs
using System;


using System.Data;
using System.Data.SqlClient;
using System.Web.Configuration;
using System.Collections.Generic;
From the Library of Wow! eBook
ptg
925
Building Database Objects with the .NET Framework
19
public class DBDataLayer
{
private static readonly string _connectionString;
public List<DBMovie> GetAll()
{
List<DBMovie> results = new List<DBMovie>();
SqlConnection con = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand(“SELECT Movie FROM DBMovies”, con);
using (con)
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
DBMovie newMovie = (DBMovie)reader[“Movie”];
results.Add(newMovie);
}
}
return results;
}
public void Insert(DBMovie movieToAdd)

{
SqlConnection con = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand(“INSERT DBMovies (Movie) VALUES (@Movie)”,

con);
cmd.Parameters.Add(“@Movie”, SqlDbType.Udt);
cmd.Parameters[“@Movie”].UdtTypeName = “DBMovie”;
cmd.Parameters[“@Movie”].Value = movieToAdd;
using (con)
{
con.Open();
cmd.ExecuteNonQuery();
}
}
static DBDataLayer()
{
_connectionString =
WebConfigurationManager.ConnectionStrings[“Movies”].ConnectionString;
}
}
From the Library of Wow! eBook
ptg
926
CHAPTER 19 Building Data Access Components with ADO.NET
The component in Listing 19.37 contains two methods: GetAll() and Insert(). The
GetAll() method retrieves all the Movie objects from the DBMovies database table. You
can cast the object represented by the DataReader directly to a DBMovie.
The Insert() method adds a new DBMovie to the DBMovies database table. The method
creates a normal ADO.NET Command object. However, a special parameter is added to the
command that represents the DBMovie object.

When you create a parameter that represents a user-defined type, you must specify a
UdtTypeName property that represents the name of the user-defined type. In Listing 19.37,
the value DBMovie is assigned to the UdtTypeName property. When the command executes,
a new DBMovie object is added to the DBMovies database table.
The page in Listing 19.38 contains a GridView, DetailsView, and ObjectDataSource control.
The GridView displays all the movies from the DBMovies database table. The DetailsView
control enables you to insert a new DBMovie into the database (see Figure 19.21).
FIGURE 19.21 Displaying and inserting DBMovie objects.
LISTING 19.38 ShowDBDataLayer.aspx
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”

<html xmlns=” >
<head id=”Head1” runat=”server”>
From the Library of Wow! eBook
ptg
927
Building Database Objects with the .NET Framework
19
<title>Show DBDataLayer</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:GridView
id=”grdMovies”
DataSourceID=”srcMovies”
Runat=”server” />
<br />
<fieldset>

<legend>Add Movie</legend>
<asp:DetailsView
id=”dtlMovie”
DataSourceID=”srcMovies”
DefaultMode=”Insert”
AutoGenerateInsertButton=”true”
AutoGenerateRows=”false”
Runat=”server”>
<Fields>
<asp:BoundField DataField=”Title” HeaderText=”Title” />
<asp:BoundField DataField=”Director” HeaderText=”Director” />
<asp:BoundField DataField=”BoxOfficeTotals”
HeaderText=”Box Office Totals” />
</Fields>
</asp:DetailsView>
</fieldset>
<asp:ObjectDataSource
id=”srcMovies”
TypeName=”DBDataLayer”
DataObjectTypeName=”DBMovie”
SelectMethod=”GetAll”
InsertMethod=”Insert”
Runat=”server” />
</div>
</form>
</body>
</html>
From the Library of Wow! eBook
ptg
928

CHAPTER 19 Building Data Access Components with ADO.NET
Creating Stored Procedures with .NET Framework
You can use .NET Framework to build a SQL stored procedure by mapping a stored proce-
dure to a method defined in a class. You must complete the following steps:
. Create an assembly that contains the stored procedure method.
. Register the assembly with SQL Server.
. Create a stored procedure based on the assembly.
In this section, we create two stored procedures with .NET Framework. The first stored
procedure, named GetRandomRow(), randomly returns a single row from a database table.
The second stored procedure, GetRandomRows(), randomly returns a set of rows from a
database table.
Creating the Stored Procedure Assembly
Creating a stored procedure with .NET Framework is easy. All you need to do is decorate
a method with the SqlProcedure attribute.
The method used for the stored procedure must satisfy two requirements. The method
must be a shared (static) method. Furthermore, the method must be implemented either
as a subroutine or as a function that returns an integer value.
Within your method, you can take advantage of the SqlPipe class to send results back to
your application. The SqlPipe class supports the following methods:
. Send()—Enables you to send a DataReader, single-row resultset, or string.
. ExecuteAndSend()—Enables you to execute a SqlCommand and send the results.
. SendResultsStart()—Enables you to initiate the sending of a resultset.
. SendResultsRow()—Enables you to send a single row of a resultset.
. SendResultsEnd()—Enables you to end the sending of a resultset.
Within the method used for creating the stored procedure, you can use ADO.NET objects
such as the SqlCommand, SqlDataReader, and SqlDataAdapter objects in the normal way.
However, rather than connect to the database by using a normal connection string, you
can create something called a context connection. A context connection enables you to
connect to the same database server as the stored procedure without authenticating.
Here’s how you can initialize a SqlConnection to use a context connection:

SqlConnection con = new SqlConnection(“context connection=true”);
You don’t specify credentials or the location of the database in the connection string.
Remember that the method actually executes within SQL Server. Therefore, you don’t
need to connect to SQL Server in the normal way.
The class in Listing 19.39 contains two methods named GetRandomRow() and
GetRandomRows(). Both methods use a SqlDataAdapter to fill a DataTable with the
From the Library of Wow! eBook
ptg
929
Building Database Objects with the .NET Framework
19
contents of the Movies database table. The GetRandomRow() method grabs a single row
from the DataTable and sends it back to the client. The GetRandomRows() method sends
multiple rows back to the client.
LISTING 19.39 RandomRows.cs
using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;
public class RandomRows
{
[SqlProcedure]
public static void GetRandomRow()
{
// Dump all records from Movies into a DataTable
SqlDataAdapter dad = new SqlDataAdapter(
“SELECT Id,Title FROM Movies”, “context connection=true”);
DataTable dtblMovies = new DataTable();
dad.Fill(dtblMovies);
// Grab a random row

Random rnd = new Random();
DataRow ranRow = dtblMovies.Rows[rnd.Next(dtblMovies.Rows.Count)];
// Build a SqlDataRecord that represents the row
SqlDataRecord result = new SqlDataRecord(
new SqlMetaData(“Id”, SqlDbType.Int), new SqlMetaData(“Title”, SqlDbType.NVarChar,

100));
result.SetSqlInt32(0, (int)ranRow[“Id”]);
result.SetSqlString(1, (string)ranRow[“Title”]);
// Send result
SqlContext.Pipe.Send(result);
}
[SqlProcedure]
public static void GetRandomRows(int rowsToReturn)
{
// Dump all records from Movies into a DataTable
SqlDataAdapter dad = new SqlDataAdapter(
“SELECT Id,Title FROM Movies”, “context connection=true”);
DataTable dtblMovies = new DataTable();
dad.Fill(dtblMovies);
From the Library of Wow! eBook
ptg
930
CHAPTER 19 Building Data Access Components with ADO.NET
// Send start record
SqlDataRecord result = new SqlDataRecord(new SqlMetaData(“Id”,
SqlDbType.Int),new SqlMetaData(“Title”, SqlDbType.NVarChar, 100));
SqlContext.Pipe.SendResultsStart(result);
Random rnd = new Random();
for (int i = 0; i < rowsToReturn; i++)

{
// Grab a random row
DataRow ranRow = dtblMovies.Rows[rnd.Next(dtblMovies.Rows.Count)];
// Set the record
result.SetSqlInt32(0, (int)ranRow[“Id”]);
result.SetSqlString(1, (string)ranRow[“Title”]);
// Send record
SqlContext.Pipe.SendResultsRow(result);
}
// Send end record
SqlContext.Pipe.SendResultsEnd();
}
}
You need to compile the RandomRows class into a separate assembly (.dll file). After you
create (and debug) the class, move the class from your App_Code folder to another folder
in your application, such as the root folder. Next, open the SDK Command prompt and
execute the following command:
csc /t:library RandomRows.cs
This command uses the C# command-line compiler to compile the RandomRows class into
an assembly.
Registering the Stored Procedure Assembly with SQL Server
After you compile the RandomRows assembly, you are ready to deploy the assembly to SQL
Server. You can load the assembly into SQL Server by executing the following command:
CREATE ASSEMBLY RandomRows
FROM ‘C:\RandomRows.dll’
You need to supply the proper path to the RandomRows.dll assembly on your hard drive. If
you need to remove the assembly, you can execute the following command:
DROP Assembly RandomRows
From the Library of Wow! eBook
ptg

931
Building Database Objects with the .NET Framework
19
Creating the Stored Procedures
Now that the assembly is loaded, you can create two stored procedures that correspond to
the two methods defined in the assembly. Execute the following two SQL commands:
CREATE PROCEDURE GetRandomRow AS
EXTERNAL NAME RandomRows.RandomRows.GetRandomRow
CREATE PROCEDURE GetRandomRows(@rowsToReturn Int) AS
EXTERNAL NAME RandomRows.RandomRows.GetRandomRows
After you execute these two commands, you have two new stored procedures named
GetRandomRow and GetRandomRows. You can treat these stored procedures just like normal
stored procedures. For example, executing the following command displays three random
movies from the Movies database:
GetRandomRows 3
If you need to delete these stored procedures, you can execute the following two commands:
DROP PROCEDURE GetRandomRow
DROP PROCEDURE GetRandomRows
Executing a .NET Stored Procedure from an ASP.NET Page
After the two stored procedures have been created, you can use the stored procedures with
an ASP.NET page. For example, the component in Listing 19.40 contains two methods
that call the two stored procedures.
LISTING 19.40 App_Code\RandomDataLayer.cs
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web.Configuration;
using System.Collections.Generic;
public class RandomDataLayer
{

private static readonly string _connectionString;
public List<String> GetRandomMovies()
{
List<String> results = new List<String>();
SqlConnection con = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand(“GetRandomRows”, con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue(“@rowsToReturn”, 5);
From the Library of Wow! eBook
ptg
932
CHAPTER 19 Building Data Access Components with ADO.NET
using (con)
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
results.Add((string)reader[“Title”]);
}
return results;
}
public static string GetRandomMovie()
{
string result = String.Empty;
SqlConnection con = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand(“GetRandomRow”, con);
cmd.CommandType = CommandType.StoredProcedure;
using (con)
{
con.Open();

SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
result = (string)reader[“Title”];
}
return result;
}
static RandomDataLayer()
{
_connectionString =
WebConfigurationManager.ConnectionStrings[“Movies”].ConnectionString;
}
}
In Listing 19.40, the GetRandomRow and GetRandomRows stored procedures are executed with
the help of SqlCommand objects.
The page in Listing 19.41 contains a GridView and ObjectDataSource control. The
ObjectDataSource control represents the RandomDataLayer component. When you request
the page, a single random movie title displays in a Label control. Furthermore, a list of
five random movie titles displays in the GridView control (see Figure 19.22).
From the Library of Wow! eBook
ptg
933
Building Database Objects with the .NET Framework
19
LISTING 19.41 ShowRandomDataLayer.aspx
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”

<script runat=”server”>
void Page_Load()
{

lblRandomMovie.Text = RandomDataLayer.GetRandomMovie();
}
</script>
<html xmlns=” >
<head id=”Head1” runat=”server”>
<title>Show RandomDataLayer</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
Random Movie:
<asp:Label
id=”lblRandomMovie”
FIGURE 19.22 Calling a .NET stored procedure from an ASP.NET page.
From the Library of Wow! eBook

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×