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

4
我是一名有用的助手,我可以为您翻译文本。

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

首先,这是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 这样做?我该如何让它避免额外的转换?

这段代码用于高负载场景,额外的转换会使其变慢。 - Dmitriy Pahovskiy
Dmitriy:这是转换(不是转化)。 - marc_s
还有:您使用的是哪个版本的SQL Server? - marc_s
1
抱歉我的英语不好 :) 我使用2008 R2 - Dmitriy Pahovskiy
1
别担心 - 你的英语比我的俄语好多了 :-) - marc_s
1个回答

5
实际上没有发生任何转换。你看到的是 Profiler/Trace 不得不将 TDS RPC 调用表示为 T-SQL 批处理,以便您可以复制粘贴并在 SSMS 中执行的结果。实际执行的 insert into XmlTable (dat) values(@data)@data 的类型/值来自请求的 ParamData 部分。与任何电线协议一样,序列化和编码必须在客户端进行,解码和反序列化必须在服务器上进行。另外,再次提醒,也没有调用 sp_execute_sql,这只是 Profiler/Trace 显示 RPC 调用的方式。

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

那是猜测。您应该基于 测量和观察 进行性能分析。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接