Супер-короткая версия:
Я решил эту проблему, когда почти закончил писать вопрос. Ответ скоро будет.
Короткая версия:
Почему SQL Server отклоняет мой XML, вставленный в типизированный столбец XML? XML генерируется с использованием System.Xml.Serialization.XmlSerializer
в .NET 4.
Гораздо длиннее версия:
У меня есть класс, который я могу успешно сериализовать, используя XmlSerializer
. Более конкретно, я могу успешно сериализовать массив этого класса, используя XmlSerializer
.
У меня есть столбец XML в таблице SQL Server 2008. Если я просто использую нетипизированный столбец XML, вставка вывода XmlSerializer.Serialize
работает нормально (я использую Entity Framework, который переводит столбец XML в тип string
). Однако я хотел бы сделать столбец типизированным XML-столбцом. Когда я делаю это, независимо от того, что я пытаюсь, я не могу получить XML от сериализатора для успешной проверки.
Вот (слегка запутанный) XSD, который я использовал для создания типизированного столбца XML в SQL Server:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ArrayOfMyObject"
targetNamespace="http://www.myproduct.com/2011/04/08/ArrayOfMyObject.xsd"
xmlns="http://www.myproduct.com/2011/04/08/ArrayOfMyObject.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="MyObject">
<xs:all minOccurs="0" maxOccurs="1">
<xs:element name="CD" type="xs:int" />
<xs:element name="CI" type="xs:string" />
<xs:element name="CT" type="xs:int" />
<xs:element name="CY" type="xs:int" />
<xs:element name="LD" type="xs:int" />
<xs:element name="SomeName" type="xs:string" />
<xs:element name="SomeNumber" type="xs:string" />
<xs:element name="SD" type="xs:int" />
<xs:element name="ZP" type="xs:string" />
<xs:element name="State">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z][A-Z]" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:all>
</xs:complexType>
<xs:element name="ArrayOfMyObject">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="MyObject" type="MyObject" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Я создал коллекцию схем в SQL Server с помощью:
CREATE XML SCHEMA COLLECTION [dbo].[MySchemaCollection] AS
'<The XSD from above>'
(делая очевидную замену здесь). Обратите внимание, что я не делать:
CREATE XML SCHEMA COLLECTION [dbo].[MySchemaCollection] AS
N'<The XSD from above which now gives an error>'
, поскольку комбинация типа NVARCHAR
с utf-8 приводит к тому, что SQL Server выдает ошибку типа:
Сообщение 9402, Уровень 16, Состояние 1, Строка 3
Синтаксический анализ XML: строка 1, символ 39, невозможно переключить кодировку
Теперь я воссоздаю свою таблицу с соответствующим столбцом:
[MyXmlColumn] [xml](DOCUMENT [dbo].[MySchemaCollection]) NULL
Я ожидаю, что то, что вставляю, будет DOCUMENT
, но я также попытался создать столбец как CONTENT
, но безрезультатно.
Я создаю XmlSerializer
как
_xml = new XmlSerializer(typeof(MyObject[]));
и вызовите сериализатор с
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("t", "http://www.myproduct.com/2011/04/08/ArrayOfMyObject.xsd");
_xml.Serialize(serializationStream, graph, ns);
где, конечно, serializationStream
- выходной поток (в данном случае MemoryStream
), а graph
имеет тип MyObject[]
.
Теперь XmlSerializer
производит вывод, такой как:
<?xml version="1.0" ?>
<ArrayOfMyObject xmlns:t="http://www.myproduct.com/2011/04/08/ArrayOfMyObject.xsd">
<MyObject>
<LD>1</LD>
<SomeName>SOME CITY 04</SomeName>
<SomeNumber>04</SomeNumber>
</MyObject>
<MyObject>
<LD>1</LD>
<SomeName>SOME CITY 05</SomeName>
<SomeNumber>05</SomeNumber>
</MyObject>
<MyObject>
<LD>1</LD>
<SomeName>SOME CITY 07</SomeName>
<SomeNumber>07</SomeNumber>
</MyObject>
<MyObject>
<LD>18</LD>
<SomeName>BANKS-FREMONT</SomeName>
<SomeNumber>BF</SomeNumber>
</MyObject>
<MyObject>
<LD>18</LD>
<SomeName>BENNINGTON</SomeName>
<SomeNumber>B000</SomeNumber>
</MyObject>
<MyObject>
<LD>18</LD>
<SomeName>CENTER</SomeName>
<SomeNumber>CE</SomeNumber>
</MyObject>
<MyObject>
<LD>18</LD>
<SomeName>FRANKLINE MAXFIELD CITY</SomeName>
<SomeNumber>FR</SomeNumber>
</MyObject>
<MyObject>
<LD>18</LD>
<SomeName>FREDERIKA LEROY CITY OF</SomeName>
<SomeNumber>FD</SomeNumber>
</MyObject>
<MyObject>
<LD>18</LD>
<SomeName>HARLAN</SomeName>
<SomeNumber>HL</SomeNumber>
</MyObject>
<MyObject>
<CT>15</CT>
<SomeName>ATLANTIC 2 AND GROVE</SomeName>
<SomeNumber>AT2</SomeNumber>
</MyObject>
<MyObject>
<CT>15</CT>
<SomeName>BRIGHTON/MARNE/GROVE 1/P</SomeName>
<SomeNumber>MR</SomeNumber>
</MyObject>
<MyObject>
<CT>15</CT>
<SomeName>EDNA/NOBLE/PLEASANT/GRIS</SomeName>
<SomeNumber>GS</SomeNumber>
</MyObject>
<MyObject>
<CT>15</CT>
<SomeName>FRANKLIN/WIOTA/GRANT/ANI</SomeName>
<SomeNumber>AN</SomeNumber>
</MyObject>
<MyObject>
<CT>15</CT>
<SomeName>MASSENA AND CITY</SomeName>
<SomeNumber>MS</SomeNumber>
</MyObject>
<MyObject>
<CT>15</CT>
<SomeName>UNION & CUMBERLAND</SomeName>
<SomeNumber>CU</SomeNumber>
</MyObject>
<MyObject>
<CD>3</CD>
<State>IA</State>
</MyObject>
<MyObject>
<CD>5</CD>
<State>IA</State>
</MyObject>
<MyObject>
<CT>1</CT>
<State>IA</State>
</MyObject>
<MyObject>
<CT>2</CT>
<State>IA</State>
</MyObject>
<MyObject>
<CT>5</CT>
<State>IA</State>
</MyObject>
</ArrayOfMyObject>
Когда я звоню Context.SaveChanges
, я получаю исключение, внутреннее сообщение об исключении которого:
Проверка XML: объявление не найдено для элемента 'ArrayOfMyObject'. Расположение: / *: ArrayOfMyObject [1]
Я попытался вызвать и / или создать сериализатор с несколькими различными параметрами пространства имен, и я получаю либо ту же ошибку, либо аналогичную (утверждая, что {http://www.myproduct.com/2011/04/08/ArrayOfMyObject.xsd}ArrayOfMyObject
ожидалось, но ArrayOfMyObject
было найдено, или наоборот Versa).
Что мне нужно изменить, чтобы XML из сериализатора проходил проверку XML на SQL Server 2008?