newProduct.Save; } /// /// Deletes an existing product /// /// Product Id public static void Deleteint id { if id < 1 throw new ArgumentException“Product Id must be greater than 0”, ➥“
Trang 1newProduct.Save();
}
/// <summary>
/// Deletes an existing product
/// </summary>
/// <param name=”id”>Product Id</param>
public static void Delete(int id)
{
if (id < 1)
throw new ArgumentException(“Product Id must be greater than 0”,
➥“id”);
SqlDataAccessLayer dataAccessLayer = new SqlDataAccessLayer();
dataAccessLayer.ProductDelete(id);
}
/// <summary>
/// Validates product information before saving product
/// properties to the database
/// </summary>
private void Save()
{
if (String.IsNullOrEmpty(_name))
throw new ArgumentException(“Product Name not supplied”, “name”);
if (_name.Length > 50)
throw new ArgumentException(“Product Name must be less than 50 characters”, “name”);
if (String.IsNullOrEmpty(_description))
throw new ArgumentException(“Product Description not supplied”,
“description”);
SqlDataAccessLayer dataAccessLayer = new SqlDataAccessLayer();
if (_id > 0)
dataAccessLayer.ProductUpdate(this);
else
dataAccessLayer.ProductInsert(this);
}
/// <summary>
/// Initializes Product
/// </summary>
/// <param name=”name”>Product Name</param>
/// <param name=”price”>Product Price</param>
/// <param name=”description”>Product Description</param>
public Product(string name, decimal price, string description)
Trang 2: this(0, name, price, description) { }
/// <summary>
/// Initializes Product
/// </summary>
/// <param name=”id”>Product Id</param>
/// <param name=”name”>Product Name</param>
/// <param name=”price”>Product Price</param>
/// <param name=”description”>Product Description</param>
public Product(int id, string name, decimal price, string description)
{
_id = id;
_name = name;
_price = price;
_description = description;
}
}
}
The Product component contains four public methods named SelectAll(), Update(),
Insert(), and Delete() All four of these methods use the SqlDataAccessLayer
compo-nent to interact with the Products database table The SqlDataAccessLayer is contained in
the Data Access layer
For example, the SelectAll() method returns a collection of Product objects This
collec-tion is retrieved from the SqlDataAccessLayer component
The Insert(), Update(), and Delete() methods validate their parameters before passing
the parameters to the Data Access layer For example, when you call the Insert() method,
the length of the Name parameter is checked to verify that it is less than 50 characters
The Business Logic layer does not contain any data access logic All this logic is contained
in the Data Access layer
Creating the Data Access Layer
The Data Access layer contains all the specialized code for interacting with a database The
Data Access layer consists of the single component in Listing 17.28 (A real-world
applica-tion might contain dozens or even hundreds of components in its Data Access layer.)
LISTING 17.28 DAL\SqlDataAccessLayer.cs
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web.Configuration;
Trang 3using System.Collections.Generic;
using AcmeStore.BusinessLogicLayer;
namespace AcmeStore.DataAccessLayer
{
/// <summary>
/// Data Access Layer for interacting with Microsoft
/// SQL Server 2008
/// </summary>
public class SqlDataAccessLayer
{
private static readonly string _connectionString = string.Empty;
/// <summary>
/// Selects all products from the database
/// </summary>
public List<Product> ProductSelectAll()
{
// Create Product collection
List<Product> colProducts = new List<Product>();
// Create connection
SqlConnection con = new SqlConnection(_connectionString);
// Create command
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = “SELECT Id,Name,Price,Description FROM Products”;
// Execute command
using (con)
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read()) {
colProducts.Add(new Product(
(int)reader[“Id”], (string)reader[“Name”], (decimal)reader[“Price”], (string)reader[“Description”]));
} }
return colProducts;
}
Trang 4/// <summary>
/// Inserts a new product into the database
/// </summary>
/// <param name=”newProduct”>Product</param>
public void ProductInsert(Product newProduct)
{
// Create connection
SqlConnection con = new SqlConnection(_connectionString);
// Create command
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = “INSERT Products (Name,Price,Description) VALUES
(@Name,@Price,
// Add parameters
cmd.Parameters.AddWithValue(“@Name”, newProduct.Name);
cmd.Parameters.AddWithValue(“@Price”, newProduct.Price);
cmd.Parameters.AddWithValue(“@Description”, newProduct.Description);
// Execute command
using (con)
{
con.Open();
cmd.ExecuteNonQuery();
}
}
/// <summary>
/// Updates an existing product into the database
/// </summary>
/// <param name=”productToUpdate”>Product</param>
public void ProductUpdate(Product productToUpdate)
{
// Create connection
SqlConnection con = new SqlConnection(_connectionString);
// Create command
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = “UPDATE Products SET
Name=@Name,Price=@Price,Description=
// Add parameters
cmd.Parameters.AddWithValue(“@Name”, productToUpdate.Name);
cmd.Parameters.AddWithValue(“@Price”, productToUpdate.Price);
Trang 5cmd.Parameters.AddWithValue(“@Description”, productToUpdate.Description);
cmd.Parameters.AddWithValue(“@Id”, productToUpdate.Id);
// Execute command
using (con)
{
con.Open();
cmd.ExecuteNonQuery();
}
}
/// <summary>
/// Deletes an existing product in the database
/// </summary>
/// <param name=”id”>Product Id</param>
public void ProductDelete(int Id)
{
// Create connection
SqlConnection con = new SqlConnection(_connectionString);
// Create command
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = “DELETE Products WHERE Id=@Id”;
// Add parameters
cmd.Parameters.AddWithValue(“@Id”, Id);
// Execute command
using (con)
{
con.Open();
cmd.ExecuteNonQuery();
}
}
/// <summary>
/// Initialize the data access layer by
/// loading the database connection string from
/// the Web.Config file
/// </summary>
static SqlDataAccessLayer()
{
Trang 6_connectionString =
WebConfigurationManager.ConnectionStrings[“Store”].ConnectionString;
if (string.IsNullOrEmpty(_connectionString))
throw new Exception(“No connection string configured in Web.Config file”);
}
}
}
The SqlDataAccessLayer component in Listing 17.28 grabs the database connection string
that it uses when communicating with Microsoft SQL Server in its constructor The
connection string is assigned to a private field so that it can be used by all the
compo-nent’s methods
The SqlDataAccessLayer component has four public methods: ProductSelectAll(),
ProductInsert(), ProductUpdate(), and ProductDelete() These methods use the
ADO.NET classes from the System.Data.SqlClient namespace to communicate with
Microsoft SQL Server
NOTE
We discuss ADO.NET in Chapter 19, “Building Data Access Components with ADO.NET.”
NOTE
In this section, the Data Access layer was built using ADO.NET It could just have as
easily been built using LINQ to SQL We discuss LINQ to SQL in Chapter 20
The SqlDataAccessLayer component is not completely isolated from the components in
the Business Logic layer The ProductSelectAll() method builds a collection of Product
objects, which the method returns to the Business Logic layer You should strive to isolate
each layer as much as possible However, in some cases, you cannot completely avoid
mixing objects from different layers
Summary
In this chapter, you learned how to build components in NET Framework In the first
part, you were given an overview of component building You learned how to take
advan-tage of dynamic compilation by using the App_Code folder You also learned how to
create component properties, methods, and constructors You also examined several
advanced topics related to components such as overloading, inheritance, MustInherit
classes, and interfaces
Trang 7In the second half of this chapter, you learned how to build component libraries You saw
different methods for compiling a set of components into an assembly You also examined
how you can add components to both an application’s Bin folder and the Global
Assembly Cache
Finally, you had a chance to consider architectural issues related to building applications
with components You learned how to build a three-tiered application, divided into
isolated User Interface, Business Logic, and Data Access layers
Trang 8Using the ObjectDataSource
Control
Representing Objects with the ObjectDataSource Control Using Parameters with the ObjectDataSource Control Paging, Sorting, and Filtering Data with the
ObjectDataSource Control Handling ObjectDataSource Control Events
Concurrency and the ObjectDataSource Control Extending the
ObjectDataSource Control Summary
The ObjectDataSource control enables you to bind
DataBound controls such as the GridView, DetailsView,
and FormView controls to a component You can use the
ObjectDataSource control to easily build multitier
applica-tions with ASP.NET Framework Unlike the SqlDataSource
control, which mixes data access logic in the User Interface
layer, the ObjectDataSource control enables you to cleanly
separate your User Interface layer from your Business Logic
and Data Access layers
In this chapter, you learn how to use the ObjectDataSource
control to represent different types of objects For example,
you learn how to use the ObjectDataSource control with
components that represent database data You also learn
how to use the ObjectDataSource control to represent
different types of method parameters
We tackle a number of advanced topics For example, you
learn how to page, sort, and filter database records
repre-sented by the ObjectDataSource control You learn how to
page and sort through large database tables efficiently
In the final section, you learn how to extend the
ObjectDataSource control to represent specialized data
sources You also learn how to extend the
ObjectDataSource control with custom parameters
Trang 9Representing Objects with the
ObjectDataSource Control
The ObjectDataSource control includes five main properties:
TypeName—The name of the type of object that the ObjectDataSource control
represents
SelectMethod—The name of a method that the ObjectDataSource calls when
selecting data
UpdateMethod—The name of a method that the ObjectDataSource calls when
updating data
InsertMethod—The name of a method that the ObjectDataSource calls when
inserting data
DeleteMethod—The name of a method that the ObjectDataSource calls when
deleting data
An ObjectDataSource control can represent any type of object in NET Framework This
section discusses several types of objects you might want to represent For example, you
learn how to use the ObjectDataSource control with components that represent
collec-tions, ADO.NET DataReaders, DataSets, LINQ to SQL queries, and web services
NOTE
You can use the ObjectDataSource control to represent any object (any class that
derives from the System.Object class) If the object does not support the
IEnumerable interface, the ObjectDataSource control automatically wraps the object
in a new object that supports the IEnumerable interface You can even represent an
ASP.NET ListBox control with an ObjectDataSource (not that a ListBox has any
inter-esting methods)
Binding to a Component
Let’s start with a simple component The component in Listing 18.1 is named
MovieCollection and contains one method named GetMovies(), which returns a
collection of movie titles
LISTING 18.1 MovieCollection.cs
using System;
using System.Web.Configuration;
using System.Collections.Generic;
public class MovieCollection
Trang 10{
public List<string> GetMovies()
{
List<string> movies = new List<string>();
movies.Add(“Star Wars”);
movies.Add(“Independence Day”);
movies.Add(“War of the Worlds”);
return movies;
}
}
You can use the page in Listing 18.2 to display the list of movies returned by the
GetMovies() method in a GridView control The page contains an ObjectDataSource
control that represents the MovieCollection component
LISTING 18.2 ShowMovieCollection.aspx
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN”
“http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Show Movie Collection</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:GridView
id=”grdMovies”
DataSourceID=”srcMovies”
Runat=”server” />
<asp:ObjectDataSource
id=”srcMovies”
TypeName=”MovieCollection”
SelectMethod=”GetMovies”
Runat=”server” />
</div>
</form>
</body>
</html>