serializacion deserializacion serialization .net-4.0 xml-serialization linq-to-xml datacontractserializer

serialization - deserializacion - Linq to Xml VS XmlSerializer VS DataContractSerializer



serializacion y deserializacion c# (3)

Elegiré XmlSerializer porque es lo más fácil de mantener para un esquema personalizado (asumiendo que tiene el XSD). Cuando haya terminado de desarrollar el sistema, pruebe su rendimiento en su totalidad y determine si la serialización XML está causando problemas. Si es así, puede reemplazarlo con algo que requiera más trabajo y probarlo nuevamente para ver si hay ganancias. Pero si la serialización XML no es un problema, entonces tiene un código que se puede mantener.

El tiempo que se tarda en analizar un pequeño fragmento de datos XML puede ser insignificante en comparación con la comunicación con la base de datos o los sistemas externos. En los sistemas con memoria grande (16GB +) puede encontrar que el GC es un cuello de botella en .NET 4 y anteriores (.NET 4.5 intenta resolver esto), especialmente cuando trabaja con conjuntos de datos y flujos muy grandes.

Utilice AutoMapper para asignar objetos creados por XSD.EXE a sus entidades. Esto permitirá que el diseño de la base de datos cambie sin afectar el servicio web.

Una cosa que es genial acerca de LINQ to XML es la validación XSD . Sin embargo, eso afecta el rendimiento.

En mi web method , obtengo un objeto de alguna clase de entidad C # de terceros. La clase de entidad no es más que el DataContract . Esta clase de entidad es bastante compleja y tiene propiedades de varios tipos, algunas propiedades también son colecciones. Por supuesto, esos tipos vinculados también son DataContracts.

Quiero serializar esa entidad DataContract en XML como parte de la lógica de negocios de mi servicio web. No puedo usar DataContractSerializer directamente (en el objeto que recibo en el método web) simplemente porque el esquema XML es completamente diferente. Por lo tanto, el XML generado por DataContractSerializer no se validará contra el esquema.

No puedo concluir el enfoque que debo seguir para la implementación. Podría pensar en los siguientes enfoques de implementación:

  1. LINQ to XML : se ve bien, pero necesito crear un árbol XML (es decir, elementos o representación XML de la instancia de clase) manualmente para cada tipo de objeto. Ya que hay muchas clases de entidades y están vinculadas entre sí, creo que esto es demasiado trabajo para escribir elementos XML manualmente. Además, tendré que seguir modificando el Árbol XML a medida que la clase de entidad presente alguna propiedad nueva. No solo esto, el código donde genero el árbol XML se vería un poco torpe (al menos en apariencia) y sería más difícil de mantener / cambiar por algún otro desarrollador en el futuro; él / ella tendrá que verlo tan de cerca para comprender cómo se genera ese XML.

  2. XmlSerializer : puedo escribir mis propias clases de entidad que representan la estructura XML que deseo. Ahora, necesito copiar los detalles del objeto entrante al objeto de mis propias clases. Así que este es un trabajo adicional (también para .NET cuando se ejecuta el código). Entonces puedo usar XmlSerializer en mi objeto para generar XML. En este caso, tendré que crear clases de entidad y cada vez que se modifique una entidad de terceros, tendré que agregar una nueva propiedad a mi clase. (con los atributos XmlElement o XmlAttibute). Pero la gente recomienda DataContractSerializer sobre este y no quiero finalizar esto a menos que todos los aspectos sean claros para mí.

  3. DataContractSerializer - De nuevo aquí, tendré que escribir mi propia clase de entidad ya que no tengo control sobre los DataContracts de terceros. Y necesito copiar los detalles del objeto entrante al objeto de mis propias clases. Así que este es un trabajo adicional. Sin embargo, dado que DataContractSerializer no admite atributos Xml, tendré que implementar IXmlSerializable y generar el Xml requerido en el método WriteXml . DataContractSerializer es más rápido que XmlSerializer, pero nuevamente tendré que manejar los cambios (en WriteXml) si la entidad de terceros cambia.

Preguntas:

  • ¿Cuál es el mejor enfoque en este escenario considerando el rendimiento también?
  • ¿Puedes sugerir algún enfoque mejor?
  • ¿Vale la pena considerar DataContractSerializer (porque tiene un mejor rendimiento sobre XmlSerilaizer ) cuando la clase de entidad entrante está sujeta a cambios?
  • ¿Debería LINQ ser realmente usado para la serialización? ¿O es realmente bueno para otras cosas además de consultar?
  • ¿Puede XmlSerializer ser preferido a LINQ en tales casos? ¿Si es así por qué?

Estoy de acuerdo con la respuesta de @Werner Strydom.

Decidí usar el XmlSerializer porque el código se puede mantener y ofrece el rendimiento que espero. Lo más importante es que me da un control total sobre la estructura XML.

Así es como resolví mi problema:

Creé clases de entidad (que representan varios tipos de elementos Xml) según mis requisitos y pasé una instancia de la clase raíz (clase que representa el elemento raíz) a través de XmlSerializer.

Pequeño uso de LINQ en caso de relación 1: M:

Siempre que quise el mismo elemento (digamos Employee ) muchas veces bajo un nodo específico (digamos Department ), declaré la propiedad de tipo List<T> . Ej. public List<Employee> Employees en la clase del Department . En tales casos, XmlSerializer obviamente agregó un elemento llamado Employees (que agrupa a todos los elementos de Employee ) en el nodo Department . En tales casos, usé LINQ ( después de que XmlSerializer serializó el objeto .NET ) para manipular el XElement (es decir, XML) generado por XmlSerializer. Usando LINQ , simplemente puse todos los nodos de Employee directamente debajo del nodo de Department y eliminé el nodo de Employees .

Sin embargo, obtuve el rendimiento esperado mediante la combinación de xmlSerializer y LINQ .

El inconveniente es que todas las clases que creé tenían que ser públicas cuando podían ser internas.

¿Por qué no DataContractSerializer y LINQ-to-XML ?

  • DataContractSerializer no permite usar atributos Xml (a menos que implemente IXmlSerializable ). Ver los tipos soportados por DataContractSerializer .
  • LINQ-to-XML (y IXmlSerializable también) hace que el código sea torpe al crear una estructura XML compleja y ese código definitivamente haría que otros desarrolladores se sorprendieran mientras lo mantenían / ​​cambiaban.

¿Hay alguna otra manera?

  • Sí. Como lo menciona @Werner Strydom, puede generar clases usando XSD.exe o herramientas como Xsd2Code y trabajar directamente con ellas si está satisfecho con las clases resultantes.

Otra opción es utilizar LINQ y Reflection para crear una clase genérica para serializar su objeto a XML. Puede encontrar un buen ejemplo de esto en http://primecoder.blogspot.com/2010/09/how-to-serialize-objects-to-xml-using.html . No estoy seguro de qué aspecto debe tener tu XML al final del día, pero si es bastante básico, esto podría hacer el truco. No necesitaría realizar cambios a medida que las clases de su entidad agreguen / eliminen / cambien las propiedades, y podría usar esto en todos sus objetos (y en otros proyectos si se almacenan en una DLL de utilidad).