大家都知道ADO.NET的DataAdapter可以使用Update方法更新dataset.在更新每一行前会调用RowUpdating,在更新完后会调用RowUpdated这两个事件.事件的顺序如下:
当使用 Update 时,每一个更新的数据行都会发生两个事件。执行顺序如下:
-
将 DataRow 中的值移至参数值。
-
引发 OnRowUpdating 事件。
-
执行命令。
-
如果该命令设置为 FirstReturnedRecord,返回的第一项结果将放置在 DataRow 中。
-
如果存在输出参数,它们将被放在 DataRow 中。
-
引发 OnRowUpdated 事件。
-
调用 AcceptChanges。
现在的是问题是如果我使用SqlCommandBuilder让DataAdapter自动生成的SQL语句到底是在OnRowUpdating 之前发生还是之后发生呢。大家可以如下代码测试看看。
private void Test2()
string _connStr = "server=bin;database=db_test;uid=sa;pwd=";
SqlConnection _conn = new SqlConnection(_connStr);
BusPrdt prdt = new BusPrdt(_connStr);
DataSet ds = new DataSet();
ds = prdt.GetData("A");
if (ds.Tables["Table1"].Rows.Count > 0)
{
ds.Tables["PRDT"].Rows[0]["NAME"] = "A1";
}
SqlDataAdapter sda = new SqlDataAdapter();
SqlCommand cmdSelect = new SqlCommand("SELECT PRD_NO,NAME FROM PRDT", _conn);
sda.SelectCommand = cmdSelect;
SqlCommandBuilder myCommandBuilder = new SqlCommandBuilder(sda);
sda.RowUpdating += new SqlRowUpdatingEventHandler(sda_RowUpdating);
sda.Update(ds, "PRDT");
}
void sda_RowUpdating(object sender, SqlRowUpdatingEventArgs e)
{
e.Row["NAME"] = "ABEFORE";
}
结果你会发现我在RowUpdating对行更新的植并没有更新到数据库中。显然生成的SQL语句的是在此之前就已经完成.
其实问题出现在RowUpdating放的位置。当我们把sda.RowUpdating += new SqlRowUpdatingEventHandler(sda_RowUpdating);
放到SqlCommandBuilder myCommandBuilder = new SqlCommandBuilder(sda);
之后时,SQL语句以及paramer里面参数就已经产生。所以必须把sda.RowUpdating += new SqlRowUpdatingEventHandler(sda_RowUpdating);
放到SqlCommandBuilder myCommandBuilder = new SqlCommandBuilder(sda);
之前调整代码如下
private void Test2()
string _connStr = "server=bin;database=db_test;uid=sa;pwd=";
SqlConnection _conn = new SqlConnection(_connStr);
BusPrdt prdt = new BusPrdt(_connStr);
DataSet ds = new DataSet();
ds = prdt.GetData("A");
if (ds.Tables["Table1"].Rows.Count > 0)
{
ds.Tables["PRDT"].Rows[0]["NAME"] = "A1";
}
SqlDataAdapter sda = new SqlDataAdapter();
SqlCommand cmdSelect = new SqlCommand("SELECT PRD_NO,NAME FROM PRDT", _conn);
sda.SelectCommand = cmdSelect;
sda.RowUpdating += new SqlRowUpdatingEventHandler(sda_RowUpdating);
SqlCommandBuilder myCommandBuilder = new SqlCommandBuilder(sda);
sda.Update(ds, "PRDT");
}
void sda_RowUpdating(object sender, SqlRowUpdatingEventArgs e)
{
e.Row["NAME"] = "ABEFORE";
}