4

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

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

CREATE TABLE [dbo].[XmlTable](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [dat] [xml] NOT NULL
)

其次,我有一个用 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();
     }
}

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

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

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

问题是:为什么SqlClient要这样做?以及如何在没有额外转换的情况下做到这一点?

4

1 回答 1

5

现实中没有发生转换。您看到的是 Profiler/Trace 的工件,必须以某种方式将TDS RPC调用表示为 T-SQL 批处理,您可以复制粘贴并在 SSMS 中执行。实际执行的文本只是类型insert into XmlTable (dat) values(@data)/@data值来自ParamData请求的一部分。与任何有线协议一样,序列化和编码必须在客户端进行,而解码和反序列化必须在服务器端进行。附带说明一下,两者都没有调用sp_execute_sql,这又是 Profiler/Trace 如何显示 RPC 调用的产物。

此代码用于高负载场景,额外的转换使其变慢

那是猜测。您应该将性能分析建立在测量和观察的基础上。

于 2012-11-29T08:46:18.293 回答