带事务的 SqlDataSource






3.88/5 (4投票s)
ASP.NET 2.0 的最佳新功能之一将是 SqlDataSource 控件。但是,正如我在实验中发现的那样,一个看似简单的控件也有一些复杂的行为需要掌握才能使其正常工作。
引言
ASP.NET 2.0 的最佳新功能之一是 SqlDataSource
控件。但是,正如我在实验中发现的那样,一个看似简单的控件也有一些复杂的行为需要掌握才能使其正常工作。
我发现网上有很多关于 SqlDataSource
的简短文章,但很少有涵盖任何细节,也没有完整的例子,只是使用了数据集和数据读取器。本文旨在带您从基本原理开始,创建一个可运行的 ASP.NET 2.0 Web 应用程序,包括选择、更新、插入和删除,以及使用事务进行并发检查。
创建新的 Web 站点
- 创建一个 ASP.NET Web 站点(我的代码用 C# 编写,所以我将建议为此示例选择 C#)。
- 将一个
GridView
拖放到 Default.aspx 页面中(默认情况下,当我们创建一个新项目时,ASP.NET 2005 IDE 将创建一个 Default.aspx)。 - 拖放一个
SqlDataSource
自定义控件。 - 使用连接字符串和 SQL 查询配置
SqlDataSource
属性。 - 选择
GridView1
并选择 GridView 任务窗格,然后选择数据源作为SqlDataSource1
。
<asp:GridView id=GridView1 EnableSortingAndPagingCallbacks="True"
PageSize="5" GridLines="None" ForeColor="#333333"
DataSourceID="SqlDataSource1" DataKeyNames="CategoryID"
CellPadding="4" AutoGenerateColumns="False"
AllowSorting="True" AllowPaging="True"
runat="server">
<FOOTERSTYLE ForeColor="White" Font-Bold="True"
BackColor="#5D7B9D" />
<COLUMNS>
<asp:BoundField SortExpression="CategoryName"
HeaderText="CategoryName"
DataField="CategoryName">
<ITEMSTYLE Width="150px" />
</asp:BoundField>
<asp:BoundField SortExpression="Description"
HeaderText="Description"
DataField="Description">
<ITEMSTYLE Width="250px" />
</asp:BoundField>
<asp:HyperLinkField Text="Edit"
DataNavigateUrlFormatString="Default2.aspx?CID={0}"
DataNavigateUrlFields="CategoryID">
<ITEMSTYLE Width="50px" />
</asp:HyperLinkField>
</COLUMNS>
<ROWSTYLE ForeColor="#333333" BackColor="#F7F6F3" />
<EDITROWSTYLE BackColor="#999999" />
<SELECTEDROWSTYLE ForeColor="#333333"
Font-Bold="True" BackColor="#E2DED6" />
<PAGERSTYLE ForeColor="White" BackColor="#284775"
HorizontalAlign="Left" />
<HEADERSTYLE ForeColor="White" Font-Bold="True"
BackColor="#5D7B9D" HorizontalAlign="Left" />
<ALTERNATINGROWSTYLE ForeColor="#284775" BackColor="White" />
</asp:GridView>
<asp:SqlDataSource id=SqlDataSource1 runat="server"
SelectCommand="SELECT [CategoryID], [CategoryName],
[Description] FROM [Categories]"
ConnectionString="<%$ConnectionStrings:NorthwindConnectionString %>">
</asp:SqlDataSource>
创建另一个 .aspx 页面,并将其命名为 Default2.aspx。
修改其中一个绑定字段为 HyperLinkField
,并分配一个 DataNavigateUrlFormatString
和您的目标页面以及相应的查询字符串。因此,当您单击该超链接时,将编辑详细信息。
<asp:HyperLinkField DataNavigateUrlFields="CategoryID"
DataNavigateUrlFormatString="Default2.aspx?CID={0}"
Text="Edit" >
<ItemStyle Width="50px" />
</asp:HyperLinkField>
现在打开 Default2.aspx 页面并创建 SqlDataSource
。
在 Default2.aspx 页面上创建所有需要的控件。
在 .NET IDE 的源编辑器中配置或编辑 Select、Update 和 Insert 参数,并编写您的 DML 语句,并为 SelectParameters
、UpdateParameters
和 InsertParameters
指定目标控件,如下所示。
对于 SelectParameters
,值来自查询字符串,因此我们需要将其配置为 QueryStringParameter
和该参数的 DataType
。
<asp:QueryStringParameter Name="CategoryID" QueryStringField="CID" Type="Int32" />
对于 UpdateParameters
,一个参数应包含 QueryStringParameter
。
<UpdateParameters>
<asp:ControlParameter Name="CategoryName" ControlID="txtName" />
<asp:ControlParameter Name="Description" ControlID="txtDesription" />
<asp:QueryStringParameter Name="CategoryID"
QueryStringField="CID" Type="Int32" />
</UpdateParameters>
对于 InsertParameters
<InsertParameters>
<asp:ControlParameter Name="CategoryName" ControlID="txtName" />
<asp:ControlParameter Name="Description" ControlID="txtDesription" />
</InsertParameters>
现在您的代码应类似于这样
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [CategoryID], [CategoryName],
[Description] FROM [Categories] WHERE ([CategoryID] = @CategoryID)"
InsertCommand="INSERT INTO Categories (CategoryName, Description)
VALUES (@CategoryName, @Description)"
UpdateCommand="UPDATE [Categories] SET
[CategoryName]= @CategoryName, [Description] = @Description
WHERE ([CategoryID] = @CategoryID)"
DataSourceMode="DataReader"
OnInserted="SqlDataSource1_Inserted"
OnInserting="SqlDataSource1_Inserting"
OnUpdated="SqlDataSource1_Updated"
OnUpdating="SqlDataSource1_Updating">
<SelectParameters>
<asp:QueryStringParameter Name="CategoryID"
QueryStringField="CID" Type="Int32" />
</SelectParameters>
<UpdateParameters>
<asp:ControlParameter Name="CategoryName"
ControlID="txtName" />
<asp:ControlParameter Name="Description"
ControlID="txtDesription" />
<asp:QueryStringParameter Name="CategoryID"
QueryStringField="CID"
Type="Int32" />
</UpdateParameters>
<InsertParameters>
<asp:ControlParameter Name="CategoryName"
ControlID="txtName" />
<asp:ControlParameter Name="Description"
ControlID="txtDesription" />
</InsertParameters>
</asp:SqlDataSource>
确保您已配置事件 OnInserted
、OnInserting
、OnUpdated
、OnUpdating
,因为本例的目的是使用事务执行数据库操作。
C# 代码,在后台代码文件中用于选择、更新和插入
您的 C# 代码应类似于以下代码,用于在页面加载时执行 Select 操作。如果该页面中存在查询字符串,它将从数据库中提取数据并显示更新模式。否则,屏幕将呈现为插入模式。
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["CID"] != null)
{
Button1.Text = "Update";
IDataReader reader = ((IDataReader)((IEnumerable)
SqlDataSource1.Select(DataSourceSelectArguments.Empty)));
while (reader.Read())
{
txtName.Text = reader["CategoryName"].ToString();
txtDesription.Text = reader["Description"].ToString();
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
try
{
if (Button1.Text != "Update")
{
SqlDataSource1.Insert();
}
else
{
SqlDataSource1.Update();
}
Response.Redirect("Default.aspx");
}
catch (Exception Ex)
{
Response.Write(Ex.Message);
}
}
protected void SqlDataSource1_Inserted(object sender,
SqlDataSourceStatusEventArgs e)
{
bool OtherProcessSucceeded = true;
if (OtherProcessSucceeded)
{
e.Command.Transaction.Commit();
Response.Write("The record was updated successfully");
}
else
{
e.Command.Transaction.Rollback();
Response.Write("The record was not updated");
}
}
protected void SqlDataSource1_Inserting(object sender,
SqlDataSourceCommandEventArgs e)
{
e.Command.Connection.Open();
e.Command.Transaction = e.Command.Connection.BeginTransaction();
}
protected void SqlDataSource1_Updated(object sender,
SqlDataSourceStatusEventArgs e)
{
bool OtherProcessSucceeded = true;
if (OtherProcessSucceeded)
{
e.Command.Transaction.Commit();
Response.Write("The record was updated successfully");
}
else
{
e.Command.Transaction.Rollback();
Response.Write("The record was not updated");
}
}
protected void SqlDataSource1_Updating(object sender,
SqlDataSourceCommandEventArgs e)
{
e.Command.Connection.Open();
e.Command.Transaction = e.Command.Connection.BeginTransaction();
}