为什么SqlClient在传递SqlXml时会使用不必要的XML转换?

Dmi*_*kiy 4 c# xml sql sql-server sqlclient

我有一个关于将xml数据类型传递给C#代码的查询的问题.

首先,这里是SQL Server上的一个表:

CREATE TABLE [dbo].[XmlTable](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [dat] [xml] NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

其次,我有一个用C#编写的应用程序.然后我XmlTable从应用程序中插入行.

这是代码:

XDocument doc = new XDocument(new XElement("root",
     new XElement("abc", "123"),
     new XElement("cba", "321")));

var reader = new XmlTextReader(new StringReader(doc.ToString()));
var xml = new SqlXml(reader);

using (var connection = new SqlConnection(_connectionString))
{
     using (var command = new SqlCommand("insert into XmlTable (dat) values(@data)", connection))
     {
          command.Parameters.Add(new SqlParameter("@data", SqlDbType.Xml){Value = xml});
          connection.Open();
          command.ExecuteNonQuery();
     }
}
Run Code Online (Sandbox Code Playgroud)

一切正常,插入行.但是,如果我运行SQL事件探查器并检查插入命令,我会看到以下内容:

declare @p3 xml
set @p3=convert(xml,N'<root><abc>123</abc><cba>321</cba></root>')
exec sp_executesql N'insert into XmlTable (dat) values(@data)',N'@data xml',@data=@p3
Run Code Online (Sandbox Code Playgroud)

我们可以看到,尽管将SqlXml类型传递给查询,仍然SqlClient执行从字符串到XML的不必要转换.XML解析器确实浪费了工作.

问题是:为什么这样SqlClient做?如何在没有额外转换的情况下完成它?

Rem*_*anu 5

在reallity中没有发生任何转换.你看到的是Profiler/Trace的工件必须以某种方式将TDS RPC调用表示为可以在SSMS中复制粘贴和执行的T-SQL批处理.执行的真实文本只是insert into XmlTable (dat) values(@data)@data类型/值来自ParamData请求的部分.与任何有线协议一样,必须在客户端中进行序列化和编码,并且必须在服务器上进行解码和反序列化.作为旁注,任何一个都没有调用sp_execute_sql,这也是Profiler/Trace如何显示RPC调用的工件.

此代码用于高负载方案,而额外的转换使其速度变慢

这是猜测.您应该对测量和观察进行性能分析.