Обычно я стараюсь держаться подальше от DataSet
с и DataTable
с, но в настоящее время у нас есть требование, в котором представляется целесообразным их использовать.
У меня возникают некоторые проблемы с сериализациейDataTable
, когда имя DataColumn
содержит пробел, а тип столбца является пользовательским типом, который я написал.
Похоже, что процесс сериализации спонтанно добавляет escape-символы к закодированному имени столбцапочти как если бы это было закодировано дважды.Это происходит только в том случае, если я использую свой собственный тип в качестве типа данных столбца, при этом отлично работает typeof(object)
.
Является ли это стандартной функцией, и если да, то знает ли кто-нибудь об этом?
Следующий пример кода демонстрирует проблему.Столбец с именем «NameWithoutSpaces» кодируется так же, как «NameWithoutSpaces», тогда как «Имя с пробелами» кодируется как «Name_x005F_x0020_With_x005F_x0020_Spaces» с дополнительными x005F символами
. При правильной записи схемы столбец получает правильнозакодирован как «Name_x0020_With_x0020_Spaces», что, как мне кажется, является причиной проблемы, поскольку этот столбец пуст после вызова методов Read *.
Согласно документации для XmlConvert.EncodeName пробелдолжно быть закодировано x0020 , а 005F используется в качестве escape-символа.Таким образом, результат, который мы получаем, выглядит так, как если бы текст был закодирован дважды с помощью этого механизма.
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; }
}
}