public static DataSet SelectSqlRows(string connectionString,
    string queryString, string tableName)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        SqlDataAdapter adapter = new SqlDataAdapter();
        adapter.SelectCommand = new SqlCommand(queryString, connection);
        SqlCommandBuilder builder = new SqlCommandBuilder(adapter);        connection.Open();        DataSet dataSet = new DataSet();
        adapter.Fill(dataSet, tableName);        //code to modify data in DataSet here        builder.GetUpdateCommand();        //Without the SqlCommandBuilder this line would fail
        adapter.Update(dataSet, tableName);
        return dataSet;
    }
}
既然最终是用SqlCommandBuilder创建SqlCommand,然后执行,为什么不直接创建一个SqlCommand,然后执行它的ExcuteNonQuery()?而是创建了Dataset,Dataadapter,还得Fill,然后adapter.Update,而adapter.Update无非就是执行了个ExcuteNonQuery.ExcuteNonQuery,在这里质疑SqlDataAdapter+SqlCommandBuilder的高效性,这是问题一;
问题二:上面如果不用SqlCommandBuilder,据说是这样“当应用程序调用 Update 方法时,DbDataAdapter 根据 DataSet 中配置的索引顺序为每一行检查 RowState 属性,并迭代执行所需的 INSERT、UPDATE 或 DELETE 语句”
那如果我只进行了一句update,当然数据库执行这句时根据 where条件也可能对表进行了大量的查找,但不一定将表全查玩就可能查找到了,而上面“当应用程序调用 Update 方法时,DbDataAdapter 根据 DataSet 中配置的索引顺序为每一行检查 RowState 属性,并迭代执行所需的 INSERT、UPDATE 或 DELETE 语句”貌似是全表迭代,那这时它的高效性?当然如果对一个表进行了比较复杂的操作,而上面一次迭代完成应该还是比较高效的。但我觉得平时写sql语句都是对表的操作,而他的“当应用程序调用 Update 方法时,DbDataAdapter 根据 DataSet 中配置的索引顺序为每一行检查 RowState 属性,并迭代执行所需的 INSERT、UPDATE 或 DELETE 语句"又是怎么实现的那?ado.net连接其他的数据库时,能实现这种吗?还是其他的数据库只实现了ado的接口?
绑定个小问题3:为什么我的CSDN自动登录主页,社区都正常,而我一点发贴有时又不正常了,要我重新登陆,登录后还不是返回发贴页面,郁闷!

解决方案 »

  1.   

    问题一:你打算把SqlCommand查询的结果放在哪?好歹你总得拿个东西"装"一下吧,后面自己接着揣摩问题二:你也可以不用SqlCommandBuilder,自己写更新语句来代替(但你得同时提供insert\update\delete这三个更新语句对象).       至于Update的时候,你只需要Update那些有更改过的数据(dataSet.AcceptChanges()\GetChanges()...\\具体哪个也记不清了)...问题三: unknown...
      

  2.   

    1.创建DataSet,创建SqlDataAdapter,完成Fill等操作,只要你要使用数据库中的数据,本来就是要做的。加上SqlCommandBuilder,无非是可以自动生成更新命令,省略手写命令的过程。
    2.这个是针对内存中已经读入的DataTable来说的,与具体的数据库无关,只是在检查完更改状态之后,生成的命令与数据库有关,与你创建的DataAdapter对象有关。但这个操作,即使你要手动保存的话,也要是做的。
    3.现在CSDN总是在抽风...
      

  3.   

    既然最终是用SqlCommandBuilder创建SqlCommand,然后执行,为什么不直接创建一个SqlCommand,然后执行它的ExcuteNonQuery()?而是创建了Dataset,Dataadapter,还得Fill从那里拿出东西总得有地方装吧,呵呵
      

  4.   

    楼上的意思是说,需要用dataGridView之类的控件显示你的数据表,这个时候DataCommandBuilder就派上用场了。可以这么理解吧。
    另外我的理解是,用ExcuteNonQuery(),是直接对数据库进行操作。而用dataSet,是数据库的副本,DataCommandBuilder的主要作用就是减轻对dataSet操作时的工作量。许多时候,DataCommandBuilder还是非常有用滴
      

  5.   

    ADO.NET技术的精华 只有在实际项目中  你才会体现出来
      

  6.   

    楼上的意思我明白,这是MSDN上的一段代码,其中的传过来的queryString不一定就是查询句子,它应该就是指的sql语句,这里更强调的是 “ 更改 ”
      

  7.   

    而问题二我想怀疑的是ado.net的强大是不是只在微软的数据库上才真正的厉害
      

  8.   

    对Oracle的支持也相当好。
    通过使用Ole DB也能使用很多其他类型的数据库,不过效率可能会低些。
      

  9.   

    1.查询无需用到SqlCommandBuilder,直接SqlDataAdapter(sqlString, connectionString).Fill()
    2.SqlCommandBuilder生成的语句,我从不手动写。如:UPDATE  dbo.user_memo
    SET         user_id = @user_id, content = @content, table_no = @table_no, mobile_no = @mobile_no, email = @email, 
                    customer_id = @customer_id, next_time = @next_time, weeks = @weeks, memo_type = @memo_type, 
                    send_type = @send_type, deleted = @deleted, state = @state, with_me = @with_me, my_phone = @my_phone, 
                    my_email = @my_email
    WHERE   (id = @Original_id) AND (user_id = @Original_user_id) AND (content = @Original_content) AND 
                    (table_no = @Original_table_no) AND (mobile_no = @Original_mobile_no) AND (email = @Original_email) AND 
                    (customer_id = @Original_customer_id) AND (next_time = @Original_next_time) AND (weeks = @Original_weeks) AND 
                    (memo_type = @Original_memo_type) AND (send_type = @Original_send_type) AND (deleted = @Original_deleted) AND 
                    (state = @Original_state) AND (with_me = @Original_with_me) AND (@IsNull_my_phone = 1) AND (my_phone IS NULL) 
                    AND (@IsNull_my_email = 1) AND (my_email IS NULL) OR
                    (id = @Original_id) AND (user_id = @Original_user_id) AND (content = @Original_content) AND 
                    (table_no = @Original_table_no) AND (mobile_no = @Original_mobile_no) AND (email = @Original_email) AND 
                    (customer_id = @Original_customer_id) AND (next_time = @Original_next_time) AND (weeks = @Original_weeks) AND 
                    (memo_type = @Original_memo_type) AND (send_type = @Original_send_type) AND (deleted = @Original_deleted) AND 
                    (state = @Original_state) AND (with_me = @Original_with_me) AND (my_phone = @Original_my_phone) AND 
                    (@IsNull_my_email = 1) AND (my_email IS NULL) OR
                    (id = @Original_id) AND (user_id = @Original_user_id) AND (content = @Original_content) AND 
                    (table_no = @Original_table_no) AND (mobile_no = @Original_mobile_no) AND (email = @Original_email) AND 
                    (customer_id = @Original_customer_id) AND (next_time = @Original_next_time) AND (weeks = @Original_weeks) AND 
                    (memo_type = @Original_memo_type) AND (send_type = @Original_send_type) AND (deleted = @Original_deleted) AND 
                    (state = @Original_state) AND (with_me = @Original_with_me) AND (@IsNull_my_phone = 1) AND (my_phone IS NULL) 
                    AND (my_email = @Original_my_email) OR
                    (id = @Original_id) AND (user_id = @Original_user_id) AND (content = @Original_content) AND 
                    (table_no = @Original_table_no) AND (mobile_no = @Original_mobile_no) AND (email = @Original_email) AND 
                    (customer_id = @Original_customer_id) AND (next_time = @Original_next_time) AND (weeks = @Original_weeks) AND 
                    (memo_type = @Original_memo_type) AND (send_type = @Original_send_type) AND (deleted = @Original_deleted) AND 
                    (state = @Original_state) AND (with_me = @Original_with_me) AND (my_phone = @Original_my_phone) AND 
                    (my_email = @Original_my_email)
    和PB一样,同一条记录,两个客户端查询出来,一个客户端修改了,这时另一个客户端是修改不了的(因为本次修改,针对的是查询出来的记录,而这条记录已被修改过,针对以前的数据进行修改,是没有意义的,对业务逻辑来讲也是不允许的。)
      

  10.   

    Dataadapter是连接外部数据库和ADO.NET内存数据集DataSet的桥梁,fill是其最重要的方法,将查询结果数据集放入内存数据对象中。
      

  11.   


    说白了,那个性能的确不高,特别是批量操作的时候,还是只能逐条记录来,效率很低,所以我Update过程基本上都是调用SqlCommand直接执行,不用SqlDataAdapter封装,更不用SqlCommandBuilder产生.
      

  12.   

    SqlCommandBuilder本身的效率就不高。不需要怀疑