I don't understand how SqlCommandBuilder does its thing. I have the following code:
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");
}
The variable builder is not used anywhere and I do not call the GetUpdateCommand() method, like they do on MSDN. I only create the SqlCommandBuilder, passing it a SqlDataAdapter. But the code just works fine.
If you look at the code, it seems like the line
var builder = new SqlCommandBuilder(da);
can be safely deleted. In fact, ReSharper is suggesting to remove it. But if I do, the code doesn't run anymore, as the SqlDataAdapter doesn't know how to perform an update.
In debug mode I noticed that after executing that line, the SqlDataAdapter's UpdateCommand property is still null. From the MSDN-docs I get that the SqlCommandBuilder registers itself to the RowUpdated event of the SqlDataAdapter.
But what does it do when that event is triggered? Is the SqlDataBuilder actually performing the update itself?
Something else I noticed, if I remove the SqlCommandBuilder, my DaRowUpdated method is triggered once, just before the InvalidOperationException occurs on the da.Update statement. I did not expect that. I'd think the RowUpdated event only occurs when a row has actually been updated.
So... three concrete questions:
- How can I prevent ReSharper from suggesting to delete this line?
- Is it bad practice to program a class like
SqlCommandBuilder, where the code doesn't indicate in any way that creating an instance is doing something with theSqlDataAdapterpassed in? - Is this a design pattern?