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:
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:
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:
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.
Comparte este post: