C# SQL Server 2012 XML类型保留大量空白

C# SQL Server 2012 XML类型保留大量空白,c#,sql-server,xml,llblgenpro,C#,Sql Server,Xml,Llblgenpro,我试图将一些数据存储在一个XML类型的列中,当数据是字符串时,该列将保留精确的文本,而不是替换或调整嵌入的行尾,特别是CR&LF 因此,像“a\r\nB\rC\nD”这样的C#字符串需要精确地返回,但XML转换似乎坚持用LF替换这些行尾,这实际上会破坏数据。我知道为什么在读取Xml文件等时会发生这种规范化,但这不是一个文件,空白是重要的 我尝试过转换(xml,N'',1) 我尝试将xml:space=“preserve”作为属性添加到包含数据的元素中 我试过使用 ;替代铬 背景资料: 我使

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

因此,像“a\r\nB\rC\nD”这样的C#字符串需要精确地返回,但XML转换似乎坚持用LF替换这些行尾,这实际上会破坏数据。我知道为什么在读取Xml文件等时会发生这种规范化,但这不是一个文件,空白是重要的

我尝试过转换(xml,N'',1)

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

我试过使用 ;替代铬

背景资料:

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

我可以合理地确定数据是在结尾未更改的情况下进入SQL Server的(我使用的XmlWriter设置是
NewLineHandling=NewLineHandling.None
并且LLBLGen将数据视为字符串),但不确定,因为复制和粘贴会更改结尾,所以我无法检查它们

Xml序列化代码基本上是包装一个字典

    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; }
    }
void IXmlSerializable.WriteXml(XmlWriter)
{
var list=新列表(value.Count);
foreach(值中的var条目)
{
添加(新条目(Entry.Key,Entry.Value));
}
Serialize(writer,list);
}
[XmlType(“条目”)]
公共结构条目
{
公共条目(字符串键,对象值):this()
{
钥匙=钥匙;
价值=价值;
}
[XmlAttribute(“键”)]
公共字符串密钥{get;set;}
[XmlElement(“值”)]
公共对象值{get;set;}
}
其中,MementorSerializer定义为:-

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

static readonly XmlSerializer MementoXmlSerializer = new XmlSerializer(typeof(List<Entry>), null, AdditionalTypes, new XmlRootAttribute("Entries"), null);
静态只读类型[]附加类型=
{
类型(int[]),
typeof(字符串[])
};
静态只读XmlSerializer MementoXmlSerializer=新XmlSerializer(typeof(List),null,AdditionalTypes,新XmlRootAttribute(“条目”),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
declare@p3 xml
set@p3=convert(xml,不适用
B
C
D')
exec sp_executesql N'UPDATE[TIPS].[dbo].[Memento]SET[Value]=@p1其中([TIPS].[dbo].[Memento].[ID]=@p2'),N'@p1 xml,@p2 int',@p1=@p3,@p2=4

感谢您的帮助。

看来,由SqlDataReader(至少在.Net 4.0中)创建的SqlXml和SqlXmlStreamWrapper实例无法更改有关如何解码Sql Server返回的二进制Xml数据的任何设置

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

4100 0D00 0A00 4200 0D00 4300 0A00 4400
我现在已经放弃了拥有xpath可搜索纪念品的想法。这本来是一个不错的选择,但我不能让我的数据不可靠地往返


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

看来,由SqlDataReader(至少在.Net 4.0中)创建的SqlXml和SqlXmlStreamWrapper实例无法更改有关如何解码Sql Server返回的二进制Xml数据的任何设置

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

4100 0D00 0A00 4200 0D00 4300 0A00 4400
我现在已经放弃了拥有xpath可搜索纪念品的想法。这本来是一个不错的选择,但我不能让我的数据不可靠地往返

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