<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>dev-ef</title><link>http://geeks.ms/blogs/dev-ef/default.aspx</link><description /><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>EF y la consistencia del grafo</title><link>http://geeks.ms/blogs/dev-ef/archive/2008/05/19/ef-y-la-consistencia-del-grafo.aspx</link><pubDate>Mon, 19 May 2008 18:09:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:86222</guid><dc:creator>Unai</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/dev-ef/rsscomments.aspx?PostID=86222</wfw:commentRss><comments>http://geeks.ms/blogs/dev-ef/archive/2008/05/19/ef-y-la-consistencia-del-grafo.aspx#comments</comments><description>&lt;p&gt;Sin lugar a dudas, la llegada de &lt;strong&gt;Entity Framework&lt;/strong&gt; va a marcar un hito importante en los desarrollos sobre plataforma &lt;strong&gt;.NET&lt;/strong&gt;; conceptualmente, nos ofrece una nueva visión del desarrollo, proporcionándonos un mecanismo sencillo para implementar Domain Driven Design (&lt;strong&gt;DDD),&lt;/strong&gt; así como innumerables ventajas de productividad. &lt;/p&gt;
&lt;p&gt;Dentro de &lt;strong&gt;EF,&lt;/strong&gt; uno de los puntos más oscuros y de los que no se habla demasiado tiene que ver con el transporte de grafos de entidades en arquitecturas orientadas a servicios. A lo largo de este artículo, trataremos de centrarnos en los distintos mecanismos de serialización existentes y en mostrar cómo éstos pueden afectar al transporte de grafos de entidades creados mediante &lt;strong&gt;Entity Framework&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Identidad de objetos contra Equivalencia de objetos &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Imagíne un sencillo escenario implementado con &lt;strong&gt;Entity Framework&lt;/strong&gt; que contenga dos tablas, Clientes y Pedidos, como se muestra en la &lt;strong&gt;figura&lt;/strong&gt; 1.&lt;strong&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/photos/unai/picture84427.aspx" target="_blank"&gt;&lt;img src="http://geeks.ms/photos/unai/images/84427/original.aspx" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="TEXT-ALIGN:center;"&gt;&lt;strong&gt;Figura 1 &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;El mapeo por defecto de &lt;strong&gt;Entity Framework&lt;/strong&gt; sobre este modelo relacional nos creará una propiedad de navegación por cada una de las entidades, de tal forma que cada cliente contendrá una propiedad que permitirá acceder a la colección de pedidos del cliente y cada pedido contendrá una propiedad que nos permitirá acceder al cliente asociado. Si sobre este modelo ejecutáramos la siguiente consulta: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt; orders = (&lt;span style="COLOR:blue;"&gt;from&lt;/span&gt; order &lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN-LEFT:106pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;in&lt;/span&gt; dbContext.Order.Include(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;Customer&amp;quot;&lt;/span&gt;) &lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN-LEFT:141pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;select&lt;/span&gt; order).ToList();&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;Podríamos encontrarnos con que muchos pedidos están asignados a un mismo cliente, y que por lo tanto la referencia obtenida mediante la propiedad de navegación de los pedidos debería ser la misma, ser idéntica, es decir el mismo objeto situado en una posición de memoria determinada y no una copia perfecta o un objeto equivalente. El elemento fundamental de &lt;strong&gt;EF&lt;/strong&gt; que nos garantiza la consistencia de los grafos de entidades es &lt;strong&gt;ObjectStateManager&lt;/strong&gt;; esta pieza nos permite además llevar el seguimiento de los cambios que sobre las entidades se producen. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ObjectStateManager&lt;/strong&gt; basa su funcionamiento en unas estructuras fundamentales denominadas &lt;strong&gt;ObjectStateEntry, &lt;/strong&gt;las cuales contienen información del estado de las entidades, su clave identificadora, un puntero hacia la entidad que representan y dos elementos de tipo &lt;strong&gt;IExtendedDataRecord&lt;/strong&gt; para almacenar los valores originales y actuales con los que poder implementar los mecanismos de actualización y/o borrado de las mismas. &lt;/p&gt;
&lt;p&gt;En la &lt;strong&gt;figura 2&lt;/strong&gt; podemos ver una imagen representativa de esta estructura. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/photos/unai/picture84428.aspx" target="_blank"&gt;&lt;img src="http://geeks.ms/photos/unai/images/84428/original.aspx" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="TEXT-ALIGN:center;"&gt;&lt;strong&gt;Figura 2 &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;En realidad, podríamos distinguir distintos tipos de &lt;strong&gt;ObjectStateEntry&lt;/strong&gt;: los referidos a entidades, los referidos a relaciones y los &amp;#39;stubs&amp;#39; . En el momento en el que una entidad es cargada dentro de un contexto de &lt;strong&gt;Entity Framework&lt;/strong&gt; se crea una nueva estructura del tipo anterior, incluyendo la información del estado por defecto, &lt;strong&gt;Unchanged&lt;/strong&gt;, la clave identificadora, un puntero hacia la entidad consultada y los valores de los elementos &lt;strong&gt;OriginalValues&lt;/strong&gt; y &lt;strong&gt;CurrentValues&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;En el caso en el que la entidad consultada contenga alguna propiedad de navegación, una asociación con la multiplicidad que fuere, además de la estructura &lt;strong&gt;ObjectStateEntry&lt;/strong&gt; para la entidad se crea también una estructura de tipo relación. Estas estructuras de tipo relación no contienen valores para las propiedades &lt;strong&gt;Entity&lt;/strong&gt; y &lt;strong&gt;EntityKey&lt;/strong&gt;; solamente necesitan la propiedad &lt;strong&gt;CurrentValues&lt;/strong&gt; para alojar un tipo &lt;strong&gt;AssociationType&lt;/strong&gt; que relacione ambos roles de la asociación. &lt;/p&gt;
&lt;p&gt;Si modificáramos la consulta anterior para obtener el primero de los pedidos encontrados en la base de datos tal y como se ve a continuación: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt; firstOrder = (&lt;span style="COLOR:blue;"&gt;from&lt;/span&gt; order &lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN-LEFT:106pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;in&lt;/span&gt; dbContext.Order &lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN-LEFT:141pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;select&lt;/span&gt; order).First(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;La estructura que tendríamos dentro del &lt;strong&gt;ObjectStateManager&lt;/strong&gt; para el caso anterior sería la mostrada en la figura 3. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/photos/unai/picture84429.aspx" target="_blank"&gt;&lt;img src="http://geeks.ms/photos/unai/images/84429/original.aspx" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="TEXT-ALIGN:center;"&gt;&lt;strong&gt;Figura 3 &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;En este caso, aunque solamente hayamos consultado una entidad simple, dentro del &lt;strong&gt;ObjectStateManager&lt;/strong&gt; dispondremos de tres estructuras &lt;strong&gt;ObjectStateEntry&lt;/strong&gt;: la primera de ellas para seguir la identidad y los cambios de la misma, una segunda estructura de tipo relación que contiene dentro de la propiedad &lt;strong&gt;CurrentValues&lt;/strong&gt;, y una asociación que relaciona a las estructuras &lt;strong&gt;ObjectStateEntry&lt;/strong&gt; involucradas. A pesar de que en la consulta anterior no hemos solicitado que se incluyera también el Cliente asociado al pedido, se ha creado una &lt;strong&gt;ObjectStateEntry&lt;/strong&gt; que contiene el valor de la propiedad &lt;strong&gt;EntityKey&lt;/strong&gt;, algo que conocemos por la clave externa de la tabla &lt;strong&gt;Order&lt;/strong&gt;. Este último caso de &lt;strong&gt;ObjectStateEntry&lt;/strong&gt; son conocidos como &amp;#39;stubs&amp;#39;, y nos permitirán guardar la consistencia de los grafos de relaciones de una forma sencilla. Si, posteriormente, lleváramos al contexto el cliente, aunque no fuera por medio de la relación, el servicio &lt;strong&gt;ObjectStateManager&lt;/strong&gt; buscaría si contiene alguna estructura &lt;strong&gt;ObjectStateEntry&lt;/strong&gt; con la propiedad &lt;strong&gt;EntityKey&lt;/strong&gt; igual a la entidad que está incluyendo, y en caso de encontrarla asignaría los valores del &lt;strong&gt;Estado&lt;/strong&gt;, &lt;strong&gt;CurrentValues&lt;/strong&gt;, &lt;strong&gt;OriginalValues&lt;/strong&gt; y crearía el puntero de la propiedad &lt;strong&gt;Entity&lt;/strong&gt; hacia la entidad incluida (ver &lt;strong&gt;figura&lt;/strong&gt; 4). &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://geeks.ms/photos/unai/picture84430.aspx" target="_blank"&gt;&lt;img src="http://geeks.ms/photos/unai/images/84430/original.aspx" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Según lo anteriormente dicho, si después de la consulta anterior ejecutáramos el siguiente trozo de código: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;if&lt;/span&gt; (!firstOrder.CustomerReference.IsLoaded) &lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN-LEFT:35pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;firstOrder.CustomerReference.Load(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;La estructura &lt;strong&gt;ObjectStateEntry&lt;/strong&gt;, de tipo &lt;strong&gt;Stub&lt;/strong&gt;, pasaría a reflejar a una entidad cargada dentro del contexto, como vemos en la &lt;strong&gt;figura 5&lt;/strong&gt;.&lt;strong&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://geeks.ms/photos/unai/picture84431.aspx" target="_blank"&gt;&lt;img src="http://geeks.ms/photos/unai/images/84431/original.aspx" border="0" alt="" /&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="TEXT-ALIGN:center;"&gt;&lt;strong&gt;Figura 5 &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Para comprobar todo lo expuesto anteriormente, veamos cómo desde código podemos consultar las entradas incluidas dentro del &lt;strong&gt;ObjectStateManager&lt;/strong&gt;, elemento al que tendremos acceso a través de un contexto de trabajo de &lt;strong&gt;Entity&lt;/strong&gt; &lt;strong&gt;Framework&lt;/strong&gt;. El siguiente trozo de código nos muestra cómo obtener las estructuras &lt;strong&gt;ObjectStateEntry&lt;/strong&gt; de tipo entidad: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;void&lt;/span&gt; DumpEntityEntries(&lt;span style="COLOR:#2b91af;"&gt;ObjectContext&lt;/span&gt; context) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Consolas;"&gt;//Obtain a ObjectStateManager reference &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;ObjectStateManager&lt;/span&gt; objectStateManager = context.ObjectStateManager; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Consolas;"&gt;//Get All unchanged entries &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;ObjectStateEntry&lt;/span&gt;&amp;gt; entries = objectStateManager.GetObjectStateEntries(System.Data.&lt;span style="COLOR:#2b91af;"&gt;EntityState&lt;/span&gt;.Unchanged); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Consolas;"&gt;//Get entity entries &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;ObjectStateEntry&lt;/span&gt;&amp;gt; entityEntry = &lt;span style="COLOR:blue;"&gt;from&lt;/span&gt; e &lt;span style="COLOR:blue;"&gt;in&lt;/span&gt; entries &lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN-LEFT:318pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;where&lt;/span&gt; !e.IsRelationship &amp;amp;&amp;amp; e.Entity != &lt;span style="COLOR:blue;"&gt;null &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;select&lt;/span&gt; e; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:green;"&gt;//Write Entity Entry &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;**** Entity Entries ***** \n&amp;quot;&lt;/span&gt;); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR:#2b91af;"&gt;ObjectStateEntry&lt;/span&gt; entry &lt;span style="COLOR:blue;"&gt;in&lt;/span&gt; entityEntry) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;\t Entity :{0}&amp;quot;&lt;/span&gt;,entry.Entity); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;"&gt;&lt;span style="FONT-FAMILY:Consolas;"&gt;}&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Bastarían unas simples modificaciones en la consulta &lt;strong&gt;LINQ&lt;/strong&gt; sobre el enumerador de las entradas para obtener las estructuras de tipo relación o de tipo &lt;strong&gt;stub&lt;/strong&gt; y ver cómo está funcionando el mecanismo de consistencia e identidad de grafos después de cada consulta. Para nuestro caso, si mostráramos la información de las entradas en el &lt;strong&gt;ObjectStateManager&lt;/strong&gt; después de obtener el primer pedido obtendríamos algo similar a lo siguiente: &lt;/p&gt;
&lt;p&gt;&lt;em&gt;**** Entity Entries **** &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Entity :IdentityGraphModel.Order &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;**** Relations Entries ***** &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Role 0: Key -&amp;gt;idCustomer Value -&amp;gt;1 &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Role 1: Key -&amp;gt;idOrder Value -&amp;gt;1 &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;**** Stub Entries ***** &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Keys: &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Name:idCustomer Value:1 &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Si lanzáramos este mismo ejemplo después de cargar el cliente asociado al primer pedido, el resultado obtenido sería algo como: &lt;/p&gt;
&lt;p&gt;&lt;em&gt;**** Entity Entries ***** &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Entity :IdentityGraphModel.Order &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Entity :IdentityGraphModel.Customer &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;**** Relations Entries ***** &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Role 0: Key -&amp;gt;idCustomer Value -&amp;gt;1 &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Role 1: Key -&amp;gt;idOrder Value -&amp;gt;1 &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;**** Stub Entries ***** &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Llegados a este punto, ya conocemos cómo se forman los grafos de entidades de &lt;strong&gt;Entity Framework&lt;/strong&gt;, y cómo efectivamente existe identidad y no equivalencia de objetos dentro de estos grafos. La pregunta ahora consiste en comprobar si esta misma consistencia e identidad de objetos se conserva al mover las entidades a través de servicios. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DataContractSerializer y XmlSerializer &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Windows Communication Foundation &lt;/strong&gt;pone a nuestra disposición dos serializadores para el transporte de mensajes entre los clientes y el servicio. &lt;strong&gt;DataContractSerializer&lt;/strong&gt; es el serializador que se usa por defecto dentro de &lt;strong&gt;WCF &lt;/strong&gt;para exponer los contratos de datos de los servicios, los cuales son decorados con los atributos &lt;strong&gt;DataContract&lt;/strong&gt; y &lt;strong&gt;DataMember &lt;/strong&gt;y que permiten compartir los esquemas y no los tipos, gracias a lo cual los servicios llegan a ser interoperables. Para los casos en los que necesitáramos tener un control más exhaustivo de la serialización de los tipos expuestos en un servicio, disponemos de &lt;strong&gt;XmlSerializer&lt;/strong&gt; y los atributos que le acompañan, como &lt;strong&gt;XmlElement&lt;/strong&gt; y &lt;strong&gt;XmlAttribute&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;Una pregunta evidente que se nos ocurre cuando intentamos transportar grafos de entidades a través de servicios de &lt;strong&gt;WCF&lt;/strong&gt; es saber si la consistencia de los mismos se mantiene. Intentaremos ver esto a través de unos sencillos ejemplos. Para ello, creamos dos contratos de datos como los que siguen: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;[&lt;span style="COLOR:#2b91af;"&gt;DataContract&lt;/span&gt;()] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Customer &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{&lt;span style="COLOR:#2b91af;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;[&lt;span style="COLOR:#2b91af;"&gt;DataMember&lt;/span&gt;()] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; FirstName { &lt;span style="COLOR:blue;"&gt;get&lt;/span&gt;; &lt;span style="COLOR:blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;[&lt;span style="COLOR:#2b91af;"&gt;DataMember&lt;/span&gt;()] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; LastName { &lt;span style="COLOR:blue;"&gt;get&lt;/span&gt;; &lt;span style="COLOR:blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;[&lt;span style="COLOR:#2b91af;"&gt;DataContract&lt;/span&gt;()] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Order &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;[&lt;span style="COLOR:#2b91af;"&gt;DataMember&lt;/span&gt;()] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Customer&lt;/span&gt; Customer { &lt;span style="COLOR:blue;"&gt;get&lt;/span&gt;; &lt;span style="COLOR:blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;[&lt;span style="COLOR:#2b91af;"&gt;DataMember&lt;/span&gt;()] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Decimal&lt;/span&gt; Total { &lt;span style="COLOR:blue;"&gt;get&lt;/span&gt;; &lt;span style="COLOR:blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;}&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;Nuestro objetivo es comprobar si la serialización de varios objetos &lt;strong&gt;Order&lt;/strong&gt; que apunten al mismo &lt;strong&gt;Customer&lt;/strong&gt; tienen esa misma representación una vez deserializados, o si no se preserva la identidad de los objetos y ésta se cambia por una equivalencia. Para ello, creamos una lista genérica de objetos &lt;strong&gt;Order&lt;/strong&gt; como sigue: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;Customer&lt;/span&gt; customer = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Customer&lt;/span&gt;(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;customer.FirstName = &lt;span style="COLOR:#a31515;"&gt;&amp;quot;Unai&amp;quot;&lt;/span&gt;; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;customer.LastName = &lt;span style="COLOR:#a31515;"&gt;&amp;quot;Zorrilla Castro&amp;quot;&lt;/span&gt;; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt; order1 = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;order1.Customer = customer; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;order1.Total = 1000M; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt; order2 = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;order2.Customer = customer; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;order2.Total = 2000M; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt; orders = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt;() { order1, order2 }; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Serializaremos esta lista genérica usando &lt;strong&gt;DataContractSerializer&lt;/strong&gt; y comprobaremos si los objetos &lt;strong&gt;order1&lt;/strong&gt; y &lt;strong&gt;order2&lt;/strong&gt; apuntan a una misma referencia, para lo que nos apoyaremos en el siguiente método: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;void&lt;/span&gt; SerializeGraph(&lt;span style="COLOR:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt; orders) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;COLOR:green;FONT-FAMILY:Consolas;"&gt;//Create data contract serializer &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;DataContractSerializer&lt;/span&gt; serializer = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;DataContractSerializer&lt;/span&gt;(&lt;span style="COLOR:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;),&lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Type&lt;/span&gt;[]{&lt;span style="COLOR:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt;)}); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;COLOR:green;FONT-FAMILY:Consolas;"&gt;//Create memory stream &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;MemoryStream&lt;/span&gt; stream = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;MemoryStream&lt;/span&gt;(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;COLOR:green;FONT-FAMILY:Consolas;"&gt;//Serialize object &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;serializer.WriteObject(stream,orders); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;COLOR:green;FONT-FAMILY:Consolas;"&gt;//Seek stream to initial position &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;stream.Seek(0,&lt;span style="COLOR:#2b91af;"&gt;SeekOrigin&lt;/span&gt;.Begin); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;COLOR:green;FONT-FAMILY:Consolas;"&gt;//Deserialize graph &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt; deserializedGraph = (&lt;span style="COLOR:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt;)serializer.ReadObject(stream); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;Is customer references equals:{0}&amp;quot;&lt;/span&gt;,&lt;span style="COLOR:#2b91af;"&gt;Object&lt;/span&gt;.ReferenceEquals(deserializedGraph[0].Customer,deserializedGraph[1].Customer)); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Si observamos el resultado, veremos que las referencias no son iguales; es decir, los objetos &lt;strong&gt;order1&lt;/strong&gt; y &lt;strong&gt;order2&lt;/strong&gt; dentro de la lista deserializada no apuntan a una misma referencia de objeto, aunque ambos contengan la misma información. Si echáramos un vistazo al mensaje transportado veríamos algo similar a lo siguiente: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Order&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;i:type&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;ArrayOfOrder&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;xmlns&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;http://schemas.datacontract.org/2004/07/GraphConsistency&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;xmlns:i&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Order&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Customer&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;FirstName&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;Unai&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;FirstName&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;LastName&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;Zorrilla Castro&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;LastName&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Customer&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Total&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;1000&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Total&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Order&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Order&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Customer&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;FirstName&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;Unai&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;FirstName&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;LastName&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;Zorrilla Castro&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;LastName&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Customer&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Total&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;2000&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Total&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Order&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Order&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Lógicamente, si usted se fija, el resultado es normal, teniendo en cuenta la información del mensaje. Dentro de los elementos &lt;strong&gt;XML&lt;/strong&gt; &lt;strong&gt;Customer&lt;/strong&gt; tenemos presente la información a transmitir, pero en ambos elementos &lt;strong&gt;Order&lt;/strong&gt; ésta se repite. Equivalencia de objetos, no hay forma alguna de que el serializador entienda que la referencia de los elementos debería ser la misma. &lt;strong&gt;DataContractSerializer&lt;/strong&gt; nos ofrece una sobrecarga, en la que podemos especificar un valor booleano para notificar a WCF que deseamos preservar la identidad de los objetos. El siguiente trozo de código modifica la construcción del serializador para indicar que deseamos preservar la identidad de los objetos. &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;DataContractSerializer&lt;/span&gt; serializer = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;DataContractSerializer&lt;/span&gt;(&lt;span style="COLOR:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;),&lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Type&lt;/span&gt;[]{&lt;span style="COLOR:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt;)},&lt;span style="COLOR:#2b91af;"&gt;Int32&lt;/span&gt;.MaxValue,&lt;span style="COLOR:blue;"&gt;false&lt;/span&gt;,&lt;span style="COLOR:blue;"&gt;true&lt;/span&gt;,&lt;span style="COLOR:blue;"&gt;null&lt;/span&gt;); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Si realizamos el mismo ejemplo con esta nueva sobrecarga, el mensaje transferido variará considerablemente, como se puede apreciar a continuación: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Order&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;z:Id&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;1&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;i:type&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;ArrayOfOrder&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;z:Size&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;2&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;xmlns&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;http://schemas.datacontract.org/2004/07/GraphConsistency&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;xmlns:i&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;xmlns:z&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;http://schemas.microsoft.com/2003/10/Serialization/&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Order&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;z:Id&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;2&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Customer&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;z:Id&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;3&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;FirstName&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;z:Id&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;4&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;Unai&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;FirstName&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;LastName&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;z:Id&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;5&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;Zorrilla Castro&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;LastName&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Customer&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Total&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;1000&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Total&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Order&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Order&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;z:Id&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;6&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Customer&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;z:Ref&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;3&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;i:nil&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;/&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Total&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;2000&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Total&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Order&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;Order&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Como puede apreciar, la presencia de los atributos &lt;strong&gt;Ref&lt;/strong&gt; e &lt;strong&gt;Id&lt;/strong&gt; permiten especificar que el contenido de un elemento está identificado dentro de otro elemento; en este caso, el objeto serializado &lt;strong&gt;order2&lt;/strong&gt; contiene dentro del elemento &lt;strong&gt;Customer&lt;/strong&gt; una referencia, &lt;strong&gt;Ref&lt;/strong&gt; con valor 3, el cual está identificado en el elemento &lt;strong&gt;Customer&lt;/strong&gt; del objeto serializado &lt;strong&gt;order1&lt;/strong&gt;. Ahora, ejecutando nuestro código veremos cómo obtenemos el comportamiento deseado y las referencias obtenidas del objeto &lt;strong&gt;Customer&lt;/strong&gt; para ambos objetos &lt;strong&gt;Order&lt;/strong&gt; son iguales. Por defecto, &lt;strong&gt;Windows Communication Foundation&lt;/strong&gt; no permite de una forma inmediata especificar que el serializador &lt;strong&gt;DataContractSerializer&lt;/strong&gt; use la preservación de las identidades de los objetos; de ahí que si usted va a transportar grafos de entidades construidos con &lt;strong&gt;Entity Framework&lt;/strong&gt; debe prestar mucha atención en este aspecto. El primer paso para especificar cómo queremos construír nuestro serializador dentro de &lt;strong&gt;WCF&lt;/strong&gt; será crear un nuevo &lt;strong&gt;DataContractSerializerOperationBehavior&lt;/strong&gt;, clase incluída dentro de &lt;strong&gt;System.ServiceModel.Description&lt;/strong&gt;, tal y como podemos ver a continuación: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;DataContractWithPreserveIdentityOperationBehavior &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;:&lt;span style="COLOR:#2b91af;"&gt;DataContractSerializerOperationBehavior &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; DataContractWithPreserveIdentityOperationBehavior(&lt;span style="COLOR:#2b91af;"&gt;OperationDescription&lt;/span&gt; operationDescription) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;:&lt;span style="COLOR:blue;"&gt;base&lt;/span&gt;(operationDescription) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;private&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;XmlObjectSerializer&lt;/span&gt; CreateDataContractSerializer(&lt;span style="COLOR:#2b91af;"&gt;Type&lt;/span&gt; type, &lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; name, &lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; ns, &lt;span style="COLOR:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Type&lt;/span&gt;&amp;gt; knownTypes) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; CreateDataContractSerializer(type, name, ns, knownTypes); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;#region&lt;/span&gt; Overrides &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;override&lt;/span&gt; System.Runtime.Serialization.&lt;span style="COLOR:#2b91af;"&gt;XmlObjectSerializer&lt;/span&gt; CreateSerializer(&lt;span style="COLOR:#2b91af;"&gt;Type&lt;/span&gt; type, &lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; name, &lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; ns, &lt;span style="COLOR:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Type&lt;/span&gt;&amp;gt; knownTypes) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; CreateDataContractSerializer(type, name, ns, knownTypes); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;override&lt;/span&gt; System.Runtime.Serialization.&lt;span style="COLOR:#2b91af;"&gt;XmlObjectSerializer&lt;/span&gt; CreateSerializer(&lt;span style="COLOR:#2b91af;"&gt;Type&lt;/span&gt; type, System.Xml.&lt;span style="COLOR:#2b91af;"&gt;XmlDictionaryString&lt;/span&gt; name, System.Xml.&lt;span style="COLOR:#2b91af;"&gt;XmlDictionaryString&lt;/span&gt; ns, &lt;span style="COLOR:#2b91af;"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Type&lt;/span&gt;&amp;gt; knownTypes) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;DataContractSerializer&lt;/span&gt;(type, name, ns, knownTypes, &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;0x7FFF &lt;span style="COLOR:green;"&gt;/*maxItemsInObjectGraph*/&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;false&lt;/span&gt;&lt;span style="COLOR:green;"&gt;/*ignoreExtensionDataObject*/&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;true&lt;/span&gt;&lt;span style="COLOR:green;"&gt;/*preserveObjectReferences*/&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;null&lt;/span&gt;&lt;span style="COLOR:green;"&gt;/*dataContractSurrogate*/&lt;/span&gt;); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;FONT-FAMILY:Consolas;"&gt;#endregion &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;}&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;Una vez creado el comportamiento para nuestro serializador, crearemos un nuevo atributo de tipo &lt;strong&gt;OperationBehavior&lt;/strong&gt; con el que decorar a los métodos de nuestro servicio que deseemos que preserven las identidades de los objetos: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;PreserveIdentityAttribute&lt;/span&gt; : &lt;span style="COLOR:#2b91af;"&gt;Attribute&lt;/span&gt;, &lt;span style="COLOR:#2b91af;"&gt;IOperationBehavior &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;#region&lt;/span&gt; IOperationBehavior Members &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;void&lt;/span&gt; AddBindingParameters(&lt;span style="COLOR:#2b91af;"&gt;OperationDescription&lt;/span&gt; description, &lt;span style="COLOR:#2b91af;"&gt;BindingParameterCollection&lt;/span&gt; parameters) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;void&lt;/span&gt; ApplyClientBehavior(&lt;span style="COLOR:#2b91af;"&gt;OperationDescription&lt;/span&gt; description, System.ServiceModel.Dispatcher.&lt;span style="COLOR:#2b91af;"&gt;ClientOperation&lt;/span&gt; proxy) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;IOperationBehavior&lt;/span&gt; innerBehavior = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;DataContractWithPreserveIdentityOperationBehavior&lt;/span&gt;(description); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;innerBehavior.ApplyClientBehavior(description, proxy); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;void&lt;/span&gt; ApplyDispatchBehavior(&lt;span style="COLOR:#2b91af;"&gt;OperationDescription&lt;/span&gt; description, System.ServiceModel.Dispatcher.&lt;span style="COLOR:#2b91af;"&gt;DispatchOperation&lt;/span&gt; dispatch) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;IOperationBehavior&lt;/span&gt; innerBehavior = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;DataContractWithPreserveIdentityOperationBehavior&lt;/span&gt;(description); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;innerBehavior.ApplyDispatchBehavior(description, dispatch); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;void&lt;/span&gt; Validate(&lt;span style="COLOR:#2b91af;"&gt;OperationDescription&lt;/span&gt; description) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;FONT-FAMILY:Consolas;"&gt;#endregion &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Con esto, ya tendríamos nuestro trabajo terminado; bastaría con aplicar el atributo anterior a los métodos de servicio que deseáramos que preservaran la identidad de los objetos dentro de un grafo. &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;[&lt;span style="COLOR:#2b91af;"&gt;ServiceContract&lt;/span&gt;(Name=&lt;span style="COLOR:#a31515;"&gt;&amp;quot;IOrderService&amp;quot;&lt;/span&gt;,Namespace=&lt;span style="COLOR:#a31515;"&gt;&amp;quot;http://www.plainconcepts.com/Oders&amp;quot;&lt;/span&gt;)] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;interface&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;IOrderService &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;[&lt;span style="COLOR:#2b91af;"&gt;OperationContract&lt;/span&gt;()] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt; GetAllOrders(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;[&lt;span style="COLOR:#2b91af;"&gt;ServiceBehavior&lt;/span&gt;()] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;OrderService &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;:&lt;span style="COLOR:#2b91af;"&gt;IOrderService &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;#region&lt;/span&gt; IOrderService Members &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;[&lt;span style="COLOR:#2b91af;"&gt;PreserveIdentity&lt;/span&gt;()] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt; GetAllOrders() &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:green;"&gt;//TODO: Implement method here &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;null&lt;/span&gt;; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;FONT-FAMILY:Consolas;"&gt;#endregion &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Consolas;"&gt;&lt;strong&gt;NOTA: &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;En estos momentos, las propiedades de navegación creadas mediante &lt;strong&gt;EDM&lt;/strong&gt; están decoradas con los atributos &lt;strong&gt;XmlIgnoreAttribute&lt;/strong&gt; y &lt;strong&gt;SoapIgnoreAttribute&lt;/strong&gt;, lo cual impide que éstas participen en los procesos de serialización con el fin de evitar posibles ciclos, algo no permitido por &lt;strong&gt;XmlSerializer&lt;/strong&gt; y &lt;strong&gt;DataContractSerializer&lt;/strong&gt;. Si decidimos incluir propiedades en clases parciales para serializar las relaciones de las entidades, debemos tener en cuenta todo lo hablado hasta este momento con el fin de preservar la identidad de los objetos. Se prevee que para la versión final deEF, en el SP1 de Visual Studio 2008 se incluyan novedades en WCF que den soporte a la serialización de propiedades de navegación. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EDITADO:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;La Beta del SP1 de Visual Studio 2008 incluye ya los cambios necesarios para dar soporte a la serialización de relaciones ( incluídos los ciclos ) y el soporte de conservación de la identidad de los objetos&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=86222" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/dev-ef/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>Cambios con el SP1 de VS2008 para Entity Framework</title><link>http://geeks.ms/blogs/dev-ef/archive/2008/05/19/cambios-con-el-sp1-de-vs2008-para-entity-framework.aspx</link><pubDate>Mon, 19 May 2008 18:08:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:86221</guid><dc:creator>Unai</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/dev-ef/rsscomments.aspx?PostID=86221</wfw:commentRss><comments>http://geeks.ms/blogs/dev-ef/archive/2008/05/19/cambios-con-el-sp1-de-vs2008-para-entity-framework.aspx#comments</comments><description>&lt;p&gt;De primeras, seguro que hay muchos que aún no he visto y que tengo ganas de probar, pero de entrada hay unos cuantos que se ven muy claros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div&gt;Nuevo diseñador, algo más ligero que el anterior y más funcional&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Por defecto los ficheros de Store, Conceptual y mapeo están embebidos en el ensamblado y no como output&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;ConcurrencyMode accesible y &amp;quot;funcional&amp;quot; desde el diseñador&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Los marcadores Setter y Getter de las propiedades accesibles y modificables desde el diseñador&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Nuevos elementos al menú contextual del Model Browser&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;La ventana de actualización del modelo es nueva, aunque le queda mucho para ser realmente funcional, sigue fallando en diversos toques para actualizar los cambios producidos en la base de datos, refrescar el modelo con una jerarquía terminada y alguna que otra, esta es una parte que está bastante floja...&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Seguimos sin tener la posiblidad de hacer tipos complejos desde el diseñador, y algo que me mosqueo es que tampoco fuí capaz de hacerlo &amp;#39;a pelo&amp;#39; ( aunque tampoco le dediqué demasiado tiempo, todo sea dicho de paso.&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;En cuanto al código el ObjectContext dispone de un nuevo método denominado CreateEntityKey mediante el cual podremos crear EntityKey pasando el nombre del EntitySet y el objeto al que le deseemos agregar este elemento.&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;La última, puede que sea una de las más importantes para la construcción de aplicaciones distribuídas y tiene que ver con la serialización de EntityCollection y EntityReferences, algo que tiene que ver con un post puesto hace algún tiempo con respecto a la &lt;a class="" title="Serialización de grafos en EF" href="http://geeks.ms/blogs/unai/archive/2008/04/29/ef-y-el-transporte-de-grafos-primeros-pasos.aspx"&gt;serialización de grafos&lt;/a&gt;.&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Seguro que me estoy olvidando de más, pero tal y como he comentado en cuanto vea más cosas interesantes las iré publicando...&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Saludos&lt;/p&gt;
&lt;p&gt;Unai Zorrilla&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=86221" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/dev-ef/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>VS2008 en castellano y Entity Framework Tools CTP</title><link>http://geeks.ms/blogs/dev-ef/archive/2008/05/16/vs2008-en-castellano-y-entity-framework-tools-ctp.aspx</link><pubDate>Fri, 16 May 2008 12:29:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:85892</guid><dc:creator>Octavio Hernández</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/dev-ef/rsscomments.aspx?PostID=85892</wfw:commentRss><comments>http://geeks.ms/blogs/dev-ef/archive/2008/05/16/vs2008-en-castellano-y-entity-framework-tools-ctp.aspx#comments</comments><description>&lt;p&gt;Quienes tengan instalado Visual Studio 2008 en castellano (u otros idiomas diferentes del inglés, probablemente) y hayan intentado instalar la CTP de las herramientas de tiempo de diseño para ADO.NET Entity Framework (siguiendo los pasos que se recomiendan &lt;a class="" title="http://www.microsoft.com/downloads/details.aspx?FamilyId=D8AE4404-8E05-41FC-94C8-C73D9E238F82&amp;amp;displaylang=en" href="http://geeks.ms/controlpanel/blogs/Entity%20Framework%20Tools%20CTP"&gt;aquí&lt;/a&gt;), seguramente al intentar crear su primer modelo de entidades habrán pensado ¿y dónde está el asistente?&lt;/p&gt;
&lt;p&gt;La respuesta está en que el asistente solo aparece cuando el entorno de desarrollo está utilizando el idioma inglés. La buena noticia es que si ha instalado VS 2008 en castellano, también tiene instalada &amp;quot;de serie&amp;quot; una versión en inglés. Basta con utilizar la opción del menú &lt;strong&gt;Herramientas | Opciones | Entorno | Configuración internacional&lt;/strong&gt;, y seleccionar el idioma &lt;strong&gt;Inglés&lt;/strong&gt;. Eso sí, el cambio no se hará efectivo hasta que cierre VS 2008 y lo vuelva a abrir.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=85892" width="1" height="1"&gt;</description></item></channel></rss>
