【发布时间】:2012-06-26 04:20:33
【问题描述】:
我不明白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 不知道如何执行更新。
在调试模式下,我注意到在执行该行之后,SqlDataAdapter 的UpdateCommand 属性仍然是null。从MSDN-docs 我知道SqlCommandBuilder 将自己注册到SqlDataAdapter 的RowUpdated 事件。
但是当那个事件被触发时它会做什么呢? SqlDataBuilder 是否真的在执行更新?
我注意到的另一件事是,如果我删除 SqlCommandBuilder,我的 DaRowUpdated 方法会在 da.Update 语句上发生 InvalidOperationException 之前触发一次。我原本没想到。我认为RowUpdated 事件仅在实际更新行时发生。
所以...三个具体问题:
- 如何防止 ReSharper 建议删除此行?
- 编写像
SqlCommandBuilder这样的类是不好的做法,其中代码没有以任何方式表明创建实例正在使用传入的SqlDataAdapter执行某些操作? - 这是design pattern吗?
【问题讨论】:
-
卸载 resharper?这对我来说很神奇。
-
您有许多实现
IDisposable的对象。将这些包裹在using块中,以确保资源被确定性地释放。我会在下面给出一个关于它的外观的答案。
标签: c# resharper dataadapter sqldataadapter sqlcommandbuilder