then multiple framework entity-framework lazy-loading eager-loading

entity-framework - then - entity framework include multiple levels



Entity Framework: ¿cuál es la diferencia entre utilizar Incluir/carga impaciente y carga diferida? (4)

Digamos que tiene dos entidades con una relación de uno a varios: Cliente y Pedido, donde cada Cliente puede tener varios Pedidos.

Al cargar una entidad de Cliente, Entity Framework le permite cargar con entusiasmo o cargar de forma lenta la colección de Pedidos del Cliente. Si elige cargar con entusiasmo la colección de pedidos, cuando recupere un cliente de la base de datos, Entity Framework generará un SQL que recupera tanto la información del cliente como los pedidos del cliente en una consulta. Sin embargo, si elige cargar de forma lenta la colección de pedidos, cuando recupere a un cliente fuera de la base de datos, Entity Framework generará un SQL que solo extraerá la información del cliente (Entity Framework generará una declaración SQL independiente si accede a la colección de pedidos del cliente más adelante). en su código).

Determinar cuándo usar la carga impaciente y cuándo usar la carga diferida se reduce a lo que espera hacer con las entidades que recupera. Si sabe que solo necesita la información de un cliente, entonces debe cargar la colección de pedidos de forma perezosa (para que la consulta SQL pueda ser eficiente al recuperar solo la información del cliente). A la inversa, si sabe que tendrá que atravesar las Órdenes de un Cliente, entonces debe cargar las Órdenes con entusiasmo (de modo que se ahorre un acierto adicional en la base de datos una vez que acceda a las Órdenes del Cliente en su código).

PS Tenga mucho cuidado al usar la carga perezosa, ya que puede llevar al problema N + 1. Por ejemplo, supongamos que tiene una página que muestra una lista de clientes y sus pedidos. Sin embargo, usted decide utilizar la carga perezosa al obtener los pedidos. Cuando recorra la colección de Clientes y luego sobre las Órdenes de cada Cliente, realizará una visita de base de datos para que cada Cliente cargue de forma lenta en su colección de Órdenes. Esto significa que para N clientes, tendrá N + 1 aciertos en la base de datos (1 acierto en la base de datos para cargar todos los Clientes, luego N aciertos en la base de datos para cargar cada uno de sus pedidos) en lugar de solo 1 acierto en la base de datos. (lo que habría recuperado todos los clientes y sus pedidos en una consulta).

He estado tratando de familiarizarme con el Entity Framework. La mayoría parece sencillo, pero estoy un poco confundido sobre la diferencia entre la carga impaciente con el método Incluir y la carga diferida predeterminada. Parece que ambos cargan entidades relacionadas, por lo que en la superficie parece que hacen lo mismo. ¿Qué me estoy perdiendo?


La carga impaciente está destinada a resolver el problema endémico N + 1 de los ORM. La versión corta es la siguiente: si va a recuperar directamente un cierto número de entidades y sabe que accederá a ciertas entidades relacionadas a través de las entidades recuperadas, es mucho más eficiente recuperar todas las entidades relacionadas por adelantado en una sola pasada. en comparación con su recuperación incremental a través de la carga perezosa.


Si vienes del mundo SQL piensa en UNIR.

Si tiene que mostrar en una cuadrícula 10 pedidos y el cliente que hizo el pedido tiene 2 opciones:

1) LAZY LOAD (= 11 consultas = SLOW PERFORMANCES)

EF realizará una consulta para recuperar los pedidos y una consulta para cada pedido para recuperar los datos del cliente.

Select * from order where order=1 + 10 x (Select * from customer where id = (order.customerId))

1) CARGA DEL EAGER (= 1 consulta = ALTAS PRESTACIONES)

EF realizará una única consulta para recuperar los pedidos y los clientes con un JOIN.

Select * from orders INNER JOIN customers on orders.customerId=customer.Id where order=1

PD: cuando recupera un objeto de la base de datos, el objeto se almacena en un caché mientras el contexto está activo. En el ejemplo que realicé con LAZY LOAD, si todas las 10 órdenes se relacionan con el mismo cliente , solo verá 2 consultas porque cuando le pida a EF que recupere un objeto, EF comprobará si el objeto está en el caché y si Encuentra que no disparará otra consulta SQL a la base de datos.


Un tema importante es la serialización. Microsoft recomienda NO usar la carga diferida predeterminada si está tratando con objetos serializados. La serialización hace que se llamen TODAS las propiedades relacionadas, lo que puede iniciar una reacción en cadena de las entidades relacionadas que se están consultando. Esto realmente entra en juego si está devolviendo datos JSON desde un controlador. Los datos JSON obviamente son serializados. Desearía devolver los datos inmediatamente a través de Eager o desactivar la carga lenta en el contexto y emplear la carga perezosa explícita.