我不明白它是怎么SqlCommandBuilder
做的。我有以下代码:
public void TestCommandBuilder()
{
var pubsDataSet = new DataSet("Pubs");
var pubs = ConfigurationManager.ConnectionStrings["PubsConnectionString"];
var connection = new SqlConnection(pubs.ConnectionString);
SqlCommand cmd = connection.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM Publishers";
var da = new SqlDataAdapter(cmd);
da.Fill(pubsDataSet, "publishers");
foreach (DataRow row in pubsDataSet.Tables["publishers"].Rows)
{
row["pub_name"] = "Updated " + DateTime.Now.Minute + DateTime.Now.Second;
}
// The variable builder is not used
var builder = new SqlCommandBuilder(da);
da.UpdateBatchSize = 3;
da.RowUpdated += DaRowUpdated;
da.Update(pubsDataSet, "publishers");
}
private void DaRowUpdated(object sender, SqlRowUpdatedEventArgs e)
{
Console.WriteLine("Rows: " + e.RecordsAffected + "\r\n");
}
该变量builder
不在任何地方使用,我也不像在MSDNGetUpdateCommand()
上那样调用该方法。我只创建,将其传递给. 但代码工作正常。SqlCommandBuilder
SqlDataAdapter
如果你看一下代码,它似乎是一行
var builder = new SqlCommandBuilder(da);
可以安全删除。事实上,ReSharper 建议删除它。但如果我这样做了,代码将不再运行,因为SqlDataAdapter
它不知道如何执行更新。
在调试模式下,我注意到在执行该行之后,SqlDataAdapter
'UpdateCommand
属性仍然是null
. 从MSDN文档中,我了解到将SqlCommandBuilder
自身注册RowUpdated
到SqlDataAdapter
.
但是当那个事件被触发时它会做什么呢?实际上是在SqlDataBuilder
执行更新本身吗?
我注意到的其他事情,如果我删除SqlCommandBuilder
,我的DaRowUpdated
方法被触发一次,就在da.Update
语句上发生 InvalidOperationException 之前。我没想到的是。我认为该RowUpdated
事件仅在实际更新行时发生。
所以......三个具体问题:
- 如何防止 ReSharper 建议删除此行?
- 编写一个像这样的类是不好的做法
SqlCommandBuilder
,其中代码没有以任何方式表明创建一个实例正在对SqlDataAdapter
传入的东西做某事? - 这是一种设计模式吗?