20

В моем web method я получаю объект некоторого третьего класса сущности C#. Класс сущности - это только DataContract. Этот класс сущностей довольно сложный и имеет свойства различных типов, некоторые свойства также являются коллекциями. Конечно, эти связанные типы также являются DataContracts.Linq to Xml VS XmlSerializer VS DataContractSerializer

Я хочу сериализовать этот объект DataContract в XML как часть бизнес-логики моего веб-сервиса. Я не могу использовать DataContractSerializer непосредственно (на объекте, который я получаю в веб-методе) просто потому, что XML-схема совсем другая. Таким образом, XML, сгенерированный DataContractSerializer, не будет проверен на соответствие схеме.

Я не могу завершить подход, который я должен выполнить для реализации. Я мог бы подумать о следующих подходах к осуществлению:

  1. LINQ к XML - Это выглядит хорошо, но мне нужно, чтобы создать XML-дерево (т.е. элементы или XML-представление экземпляра класса) вручную для каждого типа объекта. Поскольку существует много классов сущностей, и они связаны друг с другом, я думаю, что это слишком большая работа для записи XML-элементов вручную. Кроме того, мне придется продолжать модифицировать XML-дерево, когда класс сущности вводит новое свойство. Не только это, код, в котором я создаю дерево XML, выглядел бы немного неуклюжим (по крайней мере, по внешнему виду), и в будущем будет сложно поддерживать/изменять какой-либо другой разработчик; ему придется смотреть на него так близко, чтобы понять, как генерируется этот XML.

  2. XmlSerializer - я могу написать свои собственные классы сущностей, которые представляют структуру XML я хочу. Теперь мне нужно скопировать данные из входящего объекта в объект моих собственных классов. Так что это дополнительная работа (для .NET тоже при выполнении кода!). Тогда я могу использовать XmlSerializer на моем объекте для генерации XML. В этом случае мне придется создавать классы сущностей, и всякий раз, когда будет изменен сторонний объект, мне придется просто добавить новое свойство в свой класс. (с атрибутами XmlElement или XmlAttibute). Но люди рекомендуют DataContractSerializer над этим, и поэтому я не хочу дорабатывать это, если все аспекты не ясны для меня.

  3. DataContractSerializer - Снова здесь, я должен написать свой собственный класс сущностей, так как я не имею никакого контроля над DataContracts третьей стороны. И мне нужно скопировать данные из входящего объекта в объект моих собственных классов. Так что это дополнительная работа. Однако, поскольку DataContractSerializer не поддерживает атрибуты Xml, мне придется реализовать IXmlSerializable и сгенерировать требуемый Xml в методе WriteXml. DataContractSerializer быстрее, чем XmlSerializer, но снова мне придется обрабатывать изменения (в WriteXml), если изменяется сторонний объект.

Вопросы:

  • Какой подход лучше всего в этом случае с учетом производительности тоже?
  • Можете ли вы предложить лучший подход?
  • Стоит ли оценивать DataContractSerializer (потому что он имеет лучшую производительность по сравнению с XmlSerilaizer), когда класс входящего объекта может быть изменен?
  • Должен ли LINQ действительно использоваться для сериализации? Или это действительно хорошо для вещей, кроме запросов?
  • Может ли XmlSerializer быть предпочтительнее LINQ в таких случаях? Если да, то почему?

ответ

9

Я согласен с ответом @Werner Strydom.

Я решил использовать XmlSerializer, потому что код становится ремонтопригодным и предлагает производительность, которую я ожидаю. Самое главное, что он дает мне полный контроль над структурой XML.

Это, как я решить мою проблему:

я создал классы сущностей (представляющих различные типы Xml элементов) согласно моему требованию и передается экземпляр корневого класса (класс, представляющий корневой элемент) через XmlSerializer ,

Малый использование LINQ в случае 1: M отношения:

Где бы я хотел тот же элемент (скажем Employee) много раз под конкретный узел (скажем Department), я объявил свойство типа List<T>. например public List<Employee> Employees в классе Department. В таких случаях XmlSerializer явно добавил элемент с именем Employees (который представляет собой группировку всех элементов Employee) под узлом Department. В таких случаях я использовал LINQ (после того, как XmlSerializer сериализовал объект .NET), чтобы манипулировать XElement (т. Е. XML), сгенерированным XmlSerializer. Используя LINQ, я просто поместил все узлы Employee непосредственно под узел Department и удалил узел Employees.

Однако, я получил ожидаемую производительность в сочетании xmlSerializer и LINQ.

Недостатком является то, что все классы, которые я создал, должны были быть общедоступными, когда они вполне могли быть внутренними!

Почему не DataContractSerializer и LINQ-to-XML?

  • DataContractSerializer не позволяет использовать атрибуты Xml (если я не осуществлять IXmlSerializable). См. types supported by DataContractSerializer.
  • LINQ-to-XMLIXmlSerializable) делает код неуклюжим при создании сложной структуры XML, и этот код определенно заставит других разработчиков поцарапать свои головы при сохранении/изменении.

Есть ли другой способ?

  • Да. Как уже упоминалось @Werner Strydom, вы можете очень хорошо создавать классы, используя XSD.exe или инструмент вроде Xsd2Code и работать с ними напрямую, если вы довольны результирующими классами.
7

Я выберу XmlSerializer, потому что он наиболее удобен для пользовательской схемы (при условии, что у вас есть XSD). Когда вы закончите разработку системы, полностью проверьте ее производительность и определите, вызывает ли сериализация XML проблемы. Если это так, вы можете заменить его чем-то, что требует больше работы, и проверить его снова, чтобы узнать, есть ли какие-либо выгоды. Но если XML-сериализация не является проблемой, то у вас есть код для поддержки.

Время, затрачиваемое на разбор небольшого фрагмента данных XML, может быть незначительным по сравнению с общением с базой данных или внешними системами. В системах с большой памятью (16 ГБ +) вы можете обнаружить, что GC является узким местом в .NET 4 и более ранних версиях (.NET 4.5 пытается это решить), особенно когда вы работаете с очень большими наборами данных и потоками.

Использовать AutoMapper для отображения объектов, созданных XSD.EXE. Это позволит изменить дизайн базы данных, не оказывая влияния на веб-службу.

Одна вещь, которая отлично подходит для LINQ to XML: XSD validation. Однако это влияет на производительность.

1

Другой вариант - использовать LINQ и Reflection для создания универсального класса для сериализации вашего объекта в XML. Хороший пример этого можно найти по адресу http://primecoder.blogspot.com/2010/09/how-to-serialize-objects-to-xml-using.html. Я не уверен, что ваш XML должен выглядеть в конце дня, но если это довольно просто, это может сделать трюк. Вам не нужно будет вносить изменения, поскольку классы сущностей добавляют/удаляют/изменяют свойства, и вы можете использовать их для всех своих объектов (и других проектов, если они хранятся в DLL-утилите).

+0

Благодарим за сообщение. Решение, предоставленное там, не полезно для моей проблемы, но помогло узнать еще один способ использования LINQ! – Learner