C# SqlDataAdapter如何在内部工作?

C# SqlDataAdapter如何在内部工作?,c#,sql-server,database,internals,sqldataadapter,C#,Sql Server,Database,Internals,Sqldataadapter,我想知道SqlDataAdapter在内部是如何工作的,特别是当使用UpdateCommand更新一个巨大的DataTable时(因为它通常比从循环发送sql语句快得多) 以下是我的一些想法: 它创建一个准备好的sql语句(使用SqlCommand.Prepare()),其中填充了CommandText,并用正确的sql类型初始化了sql参数。然后,它在需要更新的数据行上循环,并为每个记录更新参数值,并调用SqlCommand.ExecuteNonQuery() 它创建了一组SqlComman

我想知道
SqlDataAdapter
在内部是如何工作的,特别是当使用
UpdateCommand
更新一个巨大的
DataTable
时(因为它通常比从循环发送sql语句快得多)

以下是我的一些想法:

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

它使用SQL Server客户端类的内部工具,称为命令集。您可以使用一个命令将多个批发送到SQL Server。这减少了每次呼叫的开销。您的服务器往返次数较少,诸如此类

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

不幸的是,该设施未公开披露

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

这就是说,你可以自己做得比这更快:使用TVP传输更新数据,并发出一个更新多行的
更新。这样就可以节省每批、每往返和每语句的所有开销

这样的查询如下所示:

update T set T.x = @src.x from T join @src on T.ID = @src.ID

我经常想知道,为什么问某些东西内部如何工作的人不使用像ILSpy这样的东西,只是看一眼。我假设你已经连接了一个分析器(到数据库)来查看它的功能?您的问题是什么?正如@itsme86所提到的,您可以从ILSpy-中获得很多乐趣。使用来自GAC的Open添加对System.Data的引用并进行探索!回答得好;尽管最后一条语句确实取决于更新的性质。我可能会添加一个到ILSpy的链接,并强调SqlCommandSet是
SqlDataAdapter
@dash中的一个私有字段。我想不出这样一种情况:对于许多行更新,这不是最快的方式。你能想出一个吗?对不起,我不清楚-我同意,我的意思是在原始帖子的上下文中说,如果你用许多不同的值更新了许多不同的行,那么实际上就没有一个SQL语句可以使用了(是吗?!@dash,你可以说
update t set t.x=@src.x from t join@src on t.ID=@src.ID
)。一次更新所有内容,从TVP中提取数据。非常有效的索引和索引视图维护。我明白了!我以前没见过TVP。现在我将(按惯例ab)使用它们——能够为存储的进程或函数提供一个表是非常有用的。