SQL Server 2012 XML类型保留重要的空白

时间:2013-09-16 07:39:52

标签: c# sql-server xml llblgenpro

我正在尝试将一些数据存储在XML类型的列中,当数据是字符串时,它将保留确切的文本,而不是替换或调整嵌入的行结尾,特别是CR& LF。

因此,像“A \ r \ nB \ rC \ nD”这样的C#字符串需要完全返回,但似乎XML转换仍然坚持用LF替换那些有效破坏数据的行结尾。我知道为什么在读取Xml文件等时会发生这种规范化,但这不是文件而且空格很重要。

我尝试过CONVERT(xml,N'',1);

我尝试将xml:space =“preserve”作为属性添加到包含数据的元素中。

我尝试过使用& #x D;取代CR

背景:

我正在使用CONVERT(varbinary(max), Value)检查字符串的内容,然后将输出复制到TextPad中,这样我就可以找到并确切地查看存储的字符。

我确信数据是在没有更改的情况下进入SQL Server(我使用带有NewLineHandling = NewLineHandling.None的XmlWriter设置而LLBLGen将数据视为字符串)但不确定,因为复制和粘贴更改了结尾所以我无法检查它们。

Xml序列化代码基本上包装了一个Dictionary

    void IXmlSerializable.WriteXml(XmlWriter writer)
    {
        var list = new List<Entry>(Values.Count);

        foreach (var entry in Values)
        {
            list.Add(new Entry(entry.Key, entry.Value));
        }

        MementoXmlSerializer.Serialize(writer, list);
    }

    [XmlType("Entry")]
    public struct Entry
    {
        public Entry(string key, object value): this()
        {
            Key = key;
            Value = value;
        }

        [XmlAttribute("key")]
        public string Key { get; set; }

        [XmlElement("Value")]
        public object Value { get; set; }
    }

MementoSerializer定义为: -

static readonly Type[] AdditionalTypes =
{
    typeof(int[]),
    typeof(string[])
};

static readonly XmlSerializer MementoXmlSerializer = new XmlSerializer(typeof(List<Entry>), null, AdditionalTypes, new XmlRootAttribute("Entries"), null);

LLBLGen使用并在Sql Server Profiler中看到的模式如下所示: -

declare @p3 xml
set @p3=convert(xml,N'<Entries xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Entry key="FirmName"><Value xsi:type="xsd:string">A
B
C
D</Value></Entry></Entries>')
exec sp_executesql N'UPDATE [TIPS].[dbo].[Memento] SET [Value]=@p1 WHERE ( [TIPS].[dbo].[Memento].[ID] = @p2)',N'@p1 xml,@p2 int',@p1=@p3,@p2=4

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:1)

SqlDataReader(至少在.Net 4.0中)创建的SqlXml和SqlXmlStreamWrapper实例似乎无法更改它们如何解码Sql Server返回的二进制Xml数据的任何设置。

二进制数据肯定在客户端正确接收,因为缓冲区的十六进制转储显示:

4100 0D00 0A00 4200 0D00 4300 0A00 4400

我已经放弃了现在拥有xpath-searchable纪念品的想法。这本来是一件好事,但我不能让我的数据无法可靠地进行往返。

我将Value列类型更改回NVARCHAR(MAX),现在一切正常。