SqlDataAdapter如何在内部工作?

tig*_*rou 4 c# database sql-server internals sqldataadapter

我想知道SqlDataAdapter内部是如何工作的,特别是在UpdateCommand用于更新庞大的时候DataTable(因为它通常比从循环中发送sql语句要快得多).

以下是我的想法:

  • 它创建一个准备好的sql语句(使用SqlCommand.Prepare()),其中CommandTextfill和sql参数使用正确的sql类型初始化.然后,它在需要更新的数据行上循环,对于每个记录,它更新参数值,然后调用SqlCommand.ExecuteNonQuery().
  • 它创建了一堆SqlCommand对象,里面填充了所有内容(CommandText和sql参数).然后将几个SqlCommands一次性批处理到服务器(取决于UpdateBatchSize).
  • 它使用一些特殊的,低级的或未记录的sql驱动程序指令,允许以有效的方式对多行执行更新(需要使用特殊数据格式提供要更新的行,并且相同的sql查询(UpdateCommand此处)将是对每一行执行).

usr*_*usr 6

它使用SQL Server客户端类的内部工具,称为命令集.您可以使用单个命令向SQL Server发送多个批处理.这减少了每次呼叫的开销.您有更少的服务器往返等.

每个语句更新一行,每个批次发送一个语句,但每个往返发送多个批次.这个清单中的最后一点是神奇的酱汁.

不幸的是,这个设施没有公开曝光.Ayende对此进行了攻击并为其构建了一个私有反射基础API.

如果您想了解更多信息,我建议您查看内部SqlCommandSet课程.

也就是说,您可以自己比这更快:使用TVP传输更新数据并发出UPDATE更新许多行的单个数据.这样就可以保存所有按批次,每次往返和每个语句的开销.

这样的查询看起来像这样:

update T set T.x = @src.x from T join @src on T.ID = @src.ID
Run Code Online (Sandbox Code Playgroud)