当前位置: 首页 > 面试题库 >

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

季森
2023-03-14
问题内容

我有一个关于将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事件探查器并检查insert命令,则会看到以下内容:

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要这样做?而我该如何做而无需额外转换?


问题答案:

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

此代码在高负载情况下使用,附加转换使其速度变慢

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



 类似资料:
  • 我不太喜欢JavaScript。因此,我们进行了以下修补: 我向函数传递一个字符串。一次作为基元变量,下一次作为对象属性。 之后,原始数据保持不变= 现在我想知道: 为什么它们在React中具有这些不变性特性? 我的意思是:他们说函数应该做一些事情,并提供结果。但不改变整个系统。 但如果数据还是按值传递呢?为什么有了不变性,世界变得如此重要?

  • eval 函数会在当前作用域中执行一段 JavaScript 代码字符串。 var foo = 1; function test() { var foo = 2; eval('foo = 3'); return foo; } test(); // 3 foo; // 1 但是 eval 只在被直接调用并且调用函数就是 eval 本身时,才在当前作用域中执行。 var fo

  • 我正在学习异步/等待,在阅读本文之后,不要阻塞异步代码 这是异步/等待适合于 IO 和 CPU 绑定的方法 我注意到@Stephen Cleary文章中的一个提示。 使用ConfigureAwait(false)避免死锁是一种危险的做法。您必须对阻塞代码调用的所有方法(包括所有第三方和第二方代码)的传递闭包中的每个等待使用ConfigureAwait(false)。使用ConfigureAwait

  • 当我阅读mapstruct文档时,他们说:mapstruct是一个Java注释处理器,用于生成类型安全的bean映射类。 https://mapstruct.org/documentation/stable/reference/html/#introduction 这就剩下我的任务了。为什么我需要mapstruct?Jhipster使用它,我不知道他们为什么首先需要它?为什么你需要Jhipster

  • 我读了一些关于如何使用log4j的文章。他们中的大多数给出以下代码作为开始: 或 这将初始化记录器对象。但是我的问题是为什么需要发送类类型作为参数?似乎当我使用记录器时,我不在乎在哪个类中使用它。所以类类型似乎对记录器没有影响。如果我声明一个记录器为静态和公共的,我可以在另一个类中调用这个记录器,那么作者这样设计它的意图是什么?当我使用记录器时,类类型会绑定一些东西吗?或者我可以发送任何类类型到g

  • 问题内容: 在下面的代码中,为什么我需要导入但可以不导入就可以使用? 问题答案: 为了方便起见,Java编译器会为每个源文件自动导入两个完整的软件包: java.lang包和 当前包(当前文件的包)。 请参考 oracle.com了解更多信息(http://docs.oracle.com/javase/tutorial/java/package/usepkgs.html)