我不明白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不会在任何地方使用,并且我不会像在MSDN上那样调用GetUpdateCommand()方法。我仅创建SqlCommandBuilder,并将其传递给SqlDataAdapter。但是代码工作正常。

如果您看一下代码,看起来就像这样

var builder = new SqlCommandBuilder(da);


可以安全删除。实际上,ReSharper建议删除它。但是,如果这样做,代码将不再运行,因为SqlDataAdapter不知道如何执行更新。

在调试模式下,我注意到执行该行后,SqlDataAdapterUpdateCommand属性仍然是null。从MSDN -docs中,我得到SqlCommandBuilder将自身注册到RowUpdatedSqlDataAdapter事件。

但是,触发该事件后该怎么办? SqlDataBuilder是否真正在执行更新?

我发现,如果我删除了SqlCommandBuilder,则在DaRowUpdated语句上发生InvalidOperationException之前,我的da.Update方法就会被触发一次。我没想到的是。我认为RowUpdated事件仅在实际更新某行时发生。

所以...三个具体问题:


如何防止ReSharper建议删除此行?
对像SqlCommandBuilder这样的类进行编程是一种不好的做法,其中的代码没有以任何方式表明创建实例正在通过传入的SqlDataAdapter做某事?
这是design pattern吗?

最佳答案

根据我对这个问题的评论:

    public void TestCommandBuilder()
    {
        var pubs = ConfigurationManager.ConnectionStrings["PubsConnectionString"];

        using (var pubsDataSet = new DataSet("Pubs"))
        using (var connection = new SqlConnection(pubs.ConnectionString))
        using (SqlCommand cmd = connection.CreateCommand())
        {
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "SELECT * FROM Publishers";

            using (var da = new SqlDataAdapter(cmd))
            using (new SqlCommandBuilder(da))
            {
                da.UpdateBatchSize = 3;
                da.RowUpdated += DaRowUpdated;
                da.Fill(pubsDataSet, "publishers");
                foreach (DataRow row in pubsDataSet.Tables["publishers"].Rows)
                {
                    row["pub_name"] = "Updated " + DateTime.Now.Minute + DateTime.Now.Second;
                }

                da.Update(pubsDataSet, "publishers");
            }
        }
    }

    private void DaRowUpdated(object sender, SqlRowUpdatedEventArgs e)
    {
        Console.WriteLine("Rows: " + e.RecordsAffected);
    }

09-25 21:28