void Page_Load { // Create connection string connectionString = WebConfigurationManager.ConnectionStrings[“Movies”].ConnectionString; SqlConnection con = new SqlConnectionconnectionStrin
Trang 1void Page_Load()
{
// Create connection
string connectionString =
WebConfigurationManager.ConnectionStrings[“Movies”].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
// Create Select command
dad = new SqlDataAdapter(“SELECT Id,Title,Director FROM Movies”, con);
// Create Update, Insert, and Delete commands with SqlCommandBuilder
SqlCommandBuilder builder = new SqlCommandBuilder(dad);
// Add data to DataTable
dtblMovies = new DataTable();
dad.Fill(dtblMovies);
// Bind data to Repeater
rptMovies.DataSource = dtblMovies;
rptMovies.DataBind();
}
protected void lnkUpdate_Click(object sender, EventArgs e)
{
// Update DataTable with changes
for (int i=0; i < rptMovies.Items.Count;i++)
{
RepeaterItem item = rptMovies.Items[i];
TextBox txtTitle = (TextBox)item.FindControl(“txtTitle”);
TextBox txtDirector = (TextBox)item.FindControl(“txtDirector”);
if (dtblMovies.Rows[i][“Title”] != txtTitle.Text)
dtblMovies.Rows[i][“Title”] = txtTitle.Text;
if (dtblMovies.Rows[i][“Director”] != txtDirector.Text)
dtblMovies.Rows[i][“Director”] = txtDirector.Text;
}
// Set batch size to maximum size
dad.UpdateBatchSize = 0;
// Perform update
int numUpdated = dad.Update(dtblMovies);
lblResults.Text = String.Format(“Updated {0} rows”, numUpdated);
}
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
Trang 2<title>Show DataAdapter Update</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:Repeater
id=”rptMovies”
EnableViewState=”false”
Runat=”server”>
<HeaderTemplate>
<table>
<tr>
<th>Title</th><th>Director</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:TextBox
id=”txtTitle”
Text=’<%#Eval(“Title”)%>’
Runat=”server” />
</td>
<td>
<asp:TextBox
id=”txtDirector”
Text=’<%#Eval(“Director”)%>’
Runat=”server” />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
<br />
<asp:LinkButton
id=”lnkUpdate”
Text=”Update Movies”
Runat=”server” OnClick=”lnkUpdate_Click” />
<br /><br />
Trang 3<asp:Label
id=”lblResults”
EnableViewState=”false”
Runat=”server” />
</div>
</form>
</body>
</html>
The SqlDataAdapter in Listing 19.27 performs a batch update When a SqlDataAdapter
object’s UpdateBatchSize property is set to the value 0, the SqlDataAdapter performs all
its updates in a single batch If you want to perform updates in smaller batches, you can
set the UpdateBatchSize to a particular size
Using the DataTable Object
The DataTable object represents an in-memory database table You can add rows to a
DataTable with a SqlDataAdapter, with a SqlDataReader, with an XML file, or
program-matically For example, the page in Listing 19.28 builds a new DataTable
programmati-cally The contents of the DataTable then display in a GridView control (see Figure 19.14)
FIGURE 19.14 Displaying a DataTable that was built programmatically
Trang 4LISTING 19.28 ShowDataTableProgram.aspx
<%@ Page Language=”C#” %>
<%@ Import Namespace=”System.Data” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<script runat=”server”>
void Page_Load()
{
// Create the DataTable columns
DataTable newDataTable = new DataTable();
newDataTable.Columns.Add(“Id”, typeof(int));
newDataTable.Columns.Add(“ProductName”, typeof(string));
newDataTable.Columns.Add(“ProductPrice”, typeof(decimal));
// Mark the Id column as an autoincrement column
newDataTable.Columns[“Id”].AutoIncrement = true;
// Add some data rows
for (int i = 1; i < 11; i++)
{
DataRow newRow = newDataTable.NewRow();
newRow[“ProductName”] = “Product “ + i.ToString();
newRow[“ProductPrice”] = 12.34m;
newDataTable.Rows.Add(newRow);
}
// Bind DataTable to GridView
grdProducts.DataSource = newDataTable;
grdProducts.DataBind();
}
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Show DataTable Programmatically</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<h1>Products</h1>
Trang 5<asp:GridView
id=”grdProducts”
Runat=”server” />
</div>
</form>
</body>
</html>
In Listing 19.28, a DataTable with the following three columns is created: Id,
ProductName, and ProductPrice The data type of each column is specified with a NET
Framework type For example, the ProductPrice column is created as a decimal column
Alternatively, you could create each column with a SqlType For example, you could use
System.Data.SqlTypes.SqlDecimal for the type of the ProductPrice column
The Id column is created as an autoincrement column When you add new rows to the
DataTable, the column increments its value automatically
Selecting DataRows
You can retrieve particular rows from a DataTable by using the DataTable object’s
Select() method The Select() method accepts a filter parameter You can use just about
anything that you would use in a SQL WHERE clause with the filter parameter
When you retrieve an array of rows with the Select() method, you can also specify a sort
order for the rows When specifying a sort order, you can use any expression that you
would use with a SQL ORDER BY clause
For example, the page in Listing 19.29 caches a DataTable in memory with the ASP.NET
Cache object The page contains a TextBox control When you enter a partial movie title
into the TextBox control, a list of matching movies is displayed in a GridView control The
rows are sorted in order of the movie title (see Figure 19.15)
Trang 6LISTING 19.29 ShowDataTableSelect.aspx
<%@ Page Language=”C#” %>
<%@ Import Namespace=”System.Data” %>
<%@ Import Namespace=”System.Data.SqlClient” %>
<%@ Import Namespace=”System.Web.Configuration” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<script runat=”server”>
protected void btnSearch_Click(object sender, EventArgs e)
{
// Get movies DataTable from Cache
DataTable dtblMovies = (DataTable)Cache[“MoviesToFilter”];
if (dtblMovies == null)
{
dtblMovies = GetMoviesFromDB();
Cache[“MoviesToFilter”] = dtblMovies;
}
// Select matching rows
string filter = String.Format(“Title LIKE ‘{0}*’”, txtTitle.Text);
DataRow[] rows = dtblMovies.Select(filter, “Title”);
FIGURE 19.15 Selecting matching rows from a cached DataTable
Trang 7// Bind to GridView
grdMovies.DataSource = rows;
grdMovies.DataBind();
}
private DataTable GetMoviesFromDB()
{
string connectionString =
WebConfigurationManager.ConnectionStrings[“Movies”].ConnectionString;
SqlDataAdapter dad = new SqlDataAdapter(
“SELECT Title, Director FROM Movies”, connectionString);
DataTable dtblMovies = new DataTable();
dad.Fill(dtblMovies);
return dtblMovies;
}
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<style type=”text/css”>
th, td
{
padding:5px;
}
</style>
<title>Show DataTable Select</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:TextBox
id=”txtTitle”
Tooltip=”Search”
Runat=”server” />
<asp:Button
id=”btnSearch”
Text=”Search”
Runat=”server” OnClick=”btnSearch_Click” />
<hr />
<asp:GridView
id=”grdMovies”
Trang 8Runat=”server”>
<Columns>
<asp:TemplateField HeaderText=”Title”>
<ItemTemplate>
<%# ((DataRow)Container.DataItem)[“Title”] %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText=”Director”>
<ItemTemplate>
<%# ((DataRow)Container.DataItem)[“Director”] %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
The DataTable Select() method returns an array of DataRow objects There is nothing
wrong with binding an array of DataRow objects to a GridView control However, you
must explicitly cast each data item to a DataRow and read within a GridView
TemplateField
DataRow States and DataRow Versions
When you modify the rows in a DataTable, the DataTable keeps track of the changes that
you make A DataTable maintains both the original and modified version of each row
Each row in a DataTable has a particular RowState that has one of the following values:
Unchanged—The row has not been changed
Added—The row has been added
Modified—The row has been modified
Deleted—The row has been deleted
Detached—The row has been created but not added to the DataTable
Each row in a DataTable can have more than one version Each version is represented by
one of the following values of the DataRowVersion enumeration:
Current—The current version of the row
Default—The default version of the row
Original—The original version of the row
Trang 9You can use the DataTable.AcceptChanges() method to copy the current versions of all
the rows to the original versions of all the rows And you can use the
DataTable.RejectChanges() method to copy the original versions of all the rows to the
current versions of all the rows
For example, the component in Listing 19.30 includes an AcceptChanges() and
RejectChanges() method The component maintains a DataTable in Session state If you
update a row in the DataTable, the row is updated in memory If the RejectChanges()
method is called, any changes made to the DataTable are rejected If the AcceptChanges()
method is called, the database is updated and all changes are accepted
LISTING 19.30 App_Code\Movie9.cs
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.Configuration;
public class Movie9
{
private SqlDataAdapter dad = new SqlDataAdapter();
public DataTable GetAll()
{
return (DataTable)HttpContext.Current.Session[“MoviesToEdit”];
}
public void Update(int id, string title, string director)
{
DataTable movies = (DataTable)HttpContext.Current.Session[“MoviestoEdit”];
DataRow rowToEdit = movies.Rows.Find(id);
rowToEdit[“title”] = title;
rowToEdit[“director”] = director;
}
public void RejectChanges()
{
DataTable movies = (DataTable)HttpContext.Current.Session[“MoviestoEdit”];
movies.RejectChanges();
}
Trang 10public void AcceptChanges()
{
DataTable movies = (DataTable)HttpContext.Current.Session[“MoviestoEdit”];
dad.Update(movies);
movies.AcceptChanges();
}
public Movie9()
{
// Create Data Adapter
string connectionString =
WebConfigurationManager.ConnectionStrings[“Movies”].ConnectionString;
dad = new SqlDataAdapter(
“SELECT Id,Title,Director FROM Movies”, connectionString);
SqlCommandBuilder builder = new SqlCommandBuilder(dad);
dad.UpdateBatchSize = 0;
HttpContext context = HttpContext.Current;
if (context.Session[“MoviesToEdit”] == null)
{
// Add data to DataTable
DataTable dtblMovies = new DataTable();
dad.Fill(dtblMovies);
dtblMovies.PrimaryKey = new DataColumn[] { dtblMovies.Columns[“Id”] };
context.Session[“MoviesToEdit”] = dtblMovies;
}
}
}
The page in Listing 19.31 contains a GridView that is bound to the component in Listing
19.30 The GridView includes a column that indicates whether each row has been
changed The column displays the value of the corresponding DataRow object’s RowState
property (see Figure 19.16)