Обычно я стараюсь держаться подальше от DataSet
и DataTable
, но в настоящее время у нас есть требование, в котором, кажется, имеет смысл их использовать.
У меня возникают проблемы с сериализацией DataTable
, когда имя DataColumn
содержит пробел, а тип столбца — это пользовательский тип, который я написал.
Похоже, что процесс сериализации ложно добавляет escape-символы к закодированному имени столбца, как если бы он был закодирован дважды. Это происходит только в том случае, если я использую свой собственный тип в качестве типа данных столбца, использование 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; }
}
}
Item
- person Marc Gravell   schedule 01.03.2012