LINQ To SQL: Object Identitity y múltiples objetos DataContext

Una de las grandes características de LINQ To SQL es la capacidad de preservar la identidad y consistencia de objetos al realizar consultas LINQ, incluso en el caso en el que existan varios objetos DataContext. Si dos consultas contienen resultados que se solapan, LINQ To SQL nos devuelve la misma entidad en cada conjunto de resultados de manera que la lógica de la aplicación se simplifica, pues se puede asumir que estos objetos son únicos y de hecho consistentes. Sin embargo, con las API’s tradicionales de acceso a datos, el desarrollador se ve forzado a capturar estos solapes para poder prevenir la creación de múltiples copias idénticas de resultados no únicas. ¿Cómo se gestiona la consistencia de estos objetos? A través del objeto DataContext que asegura la consistencia y unicidad de dichos objetos. Además, en el caso en el que en nuestra aplicación tengamos más de un objeto DataContext, cada uno de esos mantendrá su propia copia individual de objetos.

Un ejemplo de la preservación de la identidad de objetos en LINQ es el siguiente:

            //Preservación de objetos

            Console.WriteLine("Ejemplo de preservación de objetos");

            CLIENTES_ORMDataContext DB_New_DataContext =

                new CLIENTES_ORMDataContext();

            var c1 = DB_New_DataContext.Md_Clientes.First();

            var c2 = DB_New_DataContext.Md_Clientes.First();

            Console.WriteLine("Nombre Nº1 = {0}, Nombre Nº2={1}n c1==c2 es {2}",

                c1.NombreCliente,c2.NombreCliente,

                object.ReferenceEquals(c1,c2));

            Console.WriteLine("El tipo de c1 es {0}, y el de c2 es {1}",

                c1.GetType().ToString(), c2.GetType().ToString());

            Console.ReadLine();

La correspondiente salida por pantalla es:

image

Luego efectivamente, los objetos c1 y c2 son idénticos y hacen referencia al mismo objeto con los resultados tal y como atestigua el hecho de que tengan el mismo valor para la propiedad NombreCliente, y sobre todo porque la comparación mediante el método ReferenceEquals devuelve True como era de esperar. Por otro lado, evaluando el tipo de cada uno de los objetos (qué es resuelto dinámicamente por el compilador a partir de la característica de definir tipos implícitamente de C# 3.0) vemos que es el mismo como cabía esperar.

Como hemos comentado, esta idea de preservación de objetos en cuanto a identidad y consistencia se mantiene aún cuando tengamos múltiples objetos DataContext en nuestra aplicación. En este caso, el código que demuestra esta idea sería el siguiente:

            //Preservación de objetos

            Console.WriteLine("Ejemplo de preservación de objetos");

            CLIENTES_ORMDataContext DB_New_DataContext =

                new CLIENTES_ORMDataContext();

            var c1 = DB_New_DataContext.Md_Clientes.First();

            var c2 = DB_New_DataContext.Md_Clientes.First();

 

            Console.WriteLine("Nombre Nº1 = {0}, Nombre Nº2={1}n c1==c2 es {2}",

                c1.NombreCliente,c2.NombreCliente,

                object.ReferenceEquals(c1,c2));

            Console.WriteLine("El tipo de c1 es {0}, y el de c2 es {1}",

                c1.GetType().ToString(), c2.GetType().ToString());

            Console.ReadLine();

La correspondiente salida por pantalla es:

image

Luego vemos que efectivamente, los objetos c3 y c4 se refieren a la misma fila de resultado (consistencia), son idénticos en cuanto a tipo, pero al aplicar el método ReferenceEquals vemos que la comparación devuelve False debido a que c3 y c4 ya no se refieren al mismo objeto de resultados, sino que cada uno se refiere a un objeto distinto, ya que en cada caso tenemos un objeto DataContext diferente.

Finalmente, lo visto aplica si realizamos consultas que para un mismo DataContext devuelvan el mismo resultado: sólo se creará un objeto con los resultados. Así:

            //Preservación de objetos con varios DataContext

            Console.WriteLine("Ejemplo de preservación con una query");

            CLIENTES_ORMDataContext DB_New_DataContext3 =

                new CLIENTES_ORMDataContext();

            var query1 = DB_New_DataContext3.Md_Clientes.First(

                q1 => q1.ID_Cliente == "71505286B");

            var query2 =

                (from q2 in DB_New_DataContext3.Md_Clientes

                 where q2.ID_Cliente == "71505286B"

                 select q2).First();

 

            Console.WriteLine("Nombre Nº1 = {0}, Nombre Nº2={1}n query1==query2 es {2}",

                query1.NombreCliente, query2.NombreCliente,

                object.ReferenceEquals(query1, query2));

            Console.WriteLine("El tipo de query1 es {0}, y el de query2 es {1}",

                query1.GetType().ToString(), query2.GetType().ToString());

            Console.ReadLine();

La correspondiente salida por pantalla es:

image

Como conclusión, esta igualdad entre objetos es realmente importante para un framework de objectos relacionales como es LINQ To SQL puesto que asegura que ante una actualización del estado de una entidad, el cambio se propagará de manera consistente a lo largo de toda la aplicación.

Espero que el post os haya resultado interesante…seguiremos escribiendo sobre otras características de LINQ que estamos descubriendo y que son espectaculares.

Publicado por

Juan Carlos González

Juan Carlos es Ingeniero de Telecomunicaciones por la Universidad de Valladolid y Diplomado en Ciencias Empresariales por la Universidad Oberta de Catalunya (UOC). Cuenta con más de 12 años de experiencia en tecnologías y plataformas de Microsoft diversas (SQL Server, Visual Studio, .NET Framework, etc.), aunque su trabajo diario gira en torno a SharePoint & Office 365. Juan Carlos es MVP de Office Servers & Services desde 2015 (anteriormente fue reconocido por Microsoft como MVP de Office 365 y MVP de SharePoint Server desde 2008 hasta 2015), coordinador del grupo de usuarios .NET de Cantabria (Nuberos.Net, www.nuberos.es), co-fundador y coordinador del Grupo de Usuarios de SharePoint de España (SUGES, www.suges.es), así como co-director de la revista gratuita en castellano sobre SharePoint CompartiMOSS (www.compartimoss.com). Hasta la fecha, ha publicado 8 libros sobre SharePoint & Office 365 y varios artículos en castellano y en inglés sobre ambas plataformas.

2 comentarios en “LINQ To SQL: Object Identitity y múltiples objetos DataContext”

  1. Hola Maximiliano!
    Pues depende de a lo que te refieras:
    – Si los dos datacontext se refieren al mismo modelo relacional, sin duda la respuesta es que sí.

    – Si se refieren a distinso modelos, entiendo que también.

    Lo probaré proximamente y te comento…pero en principio no veo porque no…piensa que estamos trabajando contra objetos y el join es entre objetos, no creo que luego en la traducción al T-SQL se puedan producir cosas raras.

    Un saludo

    JC’s

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *