h1

Como carga Entity Framework los datos

Agosto 20, 2008

Imaginemos que tenemos una tabla Clientes y una tabla de Direcciones (un cliente puede tener varias direcciones) y generamos el modelo con el wizard de Visual Studio.

Si pedimos solo un objeto Cliente lo recibimos sin sus direcciones.

var ClienteObj = from p in context.Clintes select p where p.nombre=”Juan”;

Despues de estos cargamos los datos de las direcciones.

ClienteObj.Direcciones.Load();

Si volvemos a obtener el cliente, tambien se obtienen las direcciones sin tener que hacer el .Load() explicitamente. Porque?

Muy facil, Entity Framework cachea los datos para evitar viajes a la base de datos.  La primera vez que se pide un cliente la cache de EF (llamada ObjectStateManager) mantendra una vista del objeto que es devuelto. Al pedir las direcciones sucede lo mismo. La siguiente veces que pidamos el cliente, EF compara el key que es devuelto de la base de datos y descubre que ya lo tiene cacheado, de manera que devuelve el objeto cacheado que ya contenia las direcciones. Se puede controlar como se comporta la comparacion entre el objeto cacheado y el de la base de datos usando MergeOption al ejecutar la consulta:

http://msdn.microsoft.com/en-us/library/system.data.objects.mergeoption.aspx

Si se quiere obtener siempre los datos de la base de datos se debe usar MergeOption.NoTracking (pero EF no mantendra un registro de los cambios por lo que sera util principalmente en escenarios de solo lectura).

De todas maneras sigue haciendo una llamada a la base de datos para obtener un objeto que ya tiene en memoria. Como evitar esto? Tambien es muy sencillo usando el metodo GetObjectByKey (o su gemelo mas seguro, TryGetObjectByKey).

Esto lo que hace es buscar una entidad especifica (usando su EntityKey) primero en el objectContext, si no lo encuentra entonces realiza la llamada a la base de datos. De esta manera en el escenario adecuado nos podemos ahorra una llamada a la base de datos. Un escenario asi seria:

  • una sola entidad
  • no se necesitan datos relacionados
  • no se necesita sincronizacion con la base de datos.

Hay que tener en cuenta que si el objeto no esta cacheado, se devuelve solo ese objeto y no los relacionados. Pero si por ejemplo ya teniamos cargadas las direcciones de un cliente no cacheado y solicitamos ese cliente, de la base de datos se obtiene el cliente y las direcciones se obtienen del contexto.

Deja un comentario