3

通常我会尽量远离DataSets 和DataTables,但我们目前有一个要求,似乎使用它们是有意义的。

DataTableDataColumn名称包含空格并且列的类型是我编写的自定义类型时,我在序列化 a 时遇到了一些问题。

看起来序列化过程正在向编码的列名虚假地添加转义字符,几乎就像它被编码了两次一样。只有当我使用自己的类型作为列的数据类型时才会发生这种情况,使用typeof(object)效果很好。

这是一个标准功能吗?如果是的话,有人知道它的任何方法吗?

以下代码示例演示了该问题。名为“NameWithoutSpaces”的列被编码为“NameWithoutSpaces”,而“Name With Spaces”被编码为“Name_x005F_x0020_With_x005F_x0020_Spaces”,带有额外的x005F字符

在写出架构时,该列被正确编码为“Name_x0020_With_x0020_Spaces”,我猜这是问题的原因,因为一旦调用了 Read* 方法,该列就是空白的。

根据XmlConvert.EncodeName的文档,该空间应使用x0020进行编码,并且005F用作转义字符。所以,我们得到的结果似乎是如果文本通过这种机制被编码两次会发生什么。

namespace DataTableSerialization
{
    using System.Data;

    class Program
    {
        static void Main(string[] args)
        {
            var dataTable = CreateDataTable();

            var row1 = dataTable.NewRow();
            row1.ItemArray = new object[] { new Item {Value = "Data1"}, new Item {Value = "Data2"} };
            dataTable.Rows.Add(row1);

            dataTable.WriteXml(@"C:\datatable.xml");
            dataTable.WriteXmlSchema(@"C:\schema.xml");

            var dataTable2 = new DataTable();
            dataTable2.ReadXmlSchema(@"C:\schema.xml");
            dataTable2.ReadXml(@"C:\datatable.xml");
        }

        private static DataTable CreateDataTable()
        {
            var table = new DataTable { TableName = "Table" };

            var col1 = new DataColumn("NameWithoutSpaces", typeof(Item));
            var col2 = new DataColumn("Name With Spaces", typeof(Item));

            table.Columns.Add(col1);
            table.Columns.Add(col2);

            return table;
        }
    }

    public class Item
    {
        public string Value { get; set; }
    }
}
4

2 回答 2

0

您必须将 Serializable 属性设置为您的自定义对象类。

[Serializable]
public class Item     
{
    public string Value { get; set; }
} 

这是给你的一篇文章http://www.codeproject.com/Articles/1789/Object-Serialization-using-C

于 2012-04-24T20:03:10.197 回答
0

您不仅应该使用 Serializable 属性,还需要为自定义类型实现 IXmlSerializable 以在数据集中正确序列化。在我实现 IXmlSerializable 之前,我的数据集以空白列返回。

UDT 必须通过遵守 XML 序列化协定来支持与 xml 数据类型之间的转换。System.Xml.Serialization 命名空间包含用于将对象序列化为 XML 格式文档或流的类。您可以选择使用 IXmlSerializable 接口来实现 xml 序列化,该接口为 XML 序列化和反序列化提供自定义格式。

除了执行从 UDT 到 xml 的显式转换之外,XML 序列化还使您能够:

转换为 xml 数据类型后,对 UDT 实例的值使用 Xquery。

在 SQL Server 中通过本机 XML Web 服务在参数化查询和 Web 方法中使用 UDT。

使用 UDT 接收大量的 XML 数据。

序列化包含具有 UDT 列的表的数据集。

UDT 在 FOR XML 查询中没有序列化。要执行显示 UDT 的 XML 序列化的 FOR XML 查询,请在 SELECT 语句中将每个 UDT 列显式转换为 xml 数据类型。您还可以将列显式转换为 varbinary、varchar 或 nvarchar。

http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx

使用 IXmlSerializable 的优点 http://technet.microsoft.com/en-us/library/ms131082.aspx

于 2012-08-17T21:02:12.713 回答