2010-08-17 20 views

Respuesta

30

Digamos que tiene dos entidades con una relación de uno a varios: Cliente y pedido, donde cada Cliente puede tener varias Órdenes.

Al cargar una entidad Cliente, Entity Framework le permite cargar impacientemente o cargar la colección de Órdenes del Cliente. Si elige cargar ansiosamente la colección Pedidos, cuando recupera un Cliente de la base de datos, Entity Framework generará SQL que recuperará ambos la información del Cliente y los Pedidos del Cliente en una consulta. Sin embargo, si elige cargar perezosamente la colección Pedidos, cuando recupera un Cliente fuera de la base de datos, Entity Framework generará SQL que solo extrae la información del Cliente (Entity Framework generará una declaración SQL separada si accede a las Órdenes del Cliente) colección más adelante en tu código).

Determinar cuándo utilizar la carga ansiosa y cuándo usar la carga diferida todo se reduce a lo que espera hacer con las entidades que recupera. Si sabe que solo necesita la información de un Cliente, debe cargar la colección Orders (de forma que la carga de trabajo sea lenta) para que la consulta SQL pueda ser eficiente al recuperar únicamente la información del Cliente. Por el contrario, si sabe que deberá atravesar las Órdenes del Cliente, deberá cargar las Órdenes (de esta forma se ahorrará un acierto adicional en la base de datos una vez que acceda a las Órdenes del Cliente en su código).

P.S. Tenga mucho cuidado al usar la carga diferida, ya que puede ocasionar el problema N + 1. Por ejemplo, supongamos que tiene una página que muestra una lista de clientes y sus pedidos. Sin embargo, usted decide usar la carga diferida cuando obtiene las Órdenes. Cuando itera sobre la colección Clientes, luego sobre las Órdenes de cada Cliente, realizará un acierto de la base de datos para que cada Cliente lazy-load en su colección Órdenes. Esto significa que para N clientes, tendrá N + 1 aciertos en la base de datos (1 hit de la base de datos para cargar todos los Clientes, luego N hits de la base de datos para cargar cada uno de sus Pedidos) en lugar de 1 hit de la base de datos. (que habría recuperado todos los clientes y sus pedidos en una consulta).

+0

Tu respuesta no está clara. No puede usar la carga ansiosa para cargar con una consulta al cliente y todas las órdenes relacionadas con el cliente. Con la carga ansiosa puede recuperar el pedido y el cliente relacionado. –

+0

@Bugeo fue lo suficientemente claro para mí. De acuerdo, ya sé la diferencia. Pero aún así, esta es la forma en que funciona imo. –

+0

@Erik, lea el segundo párrafo. Hay un error en la respuesta. "El cliente fuera de la base de datos que Entity Framework generará SQL que recupera tanto la información del Cliente como las Órdenes del Cliente en una consulta" es falso. Recuperará solo una orden, no todas las órdenes. –

6

La carga ansiosa tiene como objetivo resolver el problema N+1 Selects endémico de los ORM. La versión corta es la siguiente: si va a recuperar directamente un número de entidades y sabe que accederá a ciertas entidades relacionadas a través de las entidades recuperadas, es mucho más más eficiente para recuperar todas las entidades relacionadas por adelantado en una pasar, en comparación con recuperarlos incrementalmente a través de la carga diferida.

17

Si viene del mundo SQL, piense en JOIN.

Si usted tiene que mostrar en una cuadrícula de 10 órdenes y el cliente que puso el orden que tienen 2 opciones:

1) Lazy Load (= 11 queryes = PRESTACIONES lento)

EF tiro una consulta para recuperar los pedidos y una consulta para cada orden para recuperar los datos del cliente.

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

1) CARGA EAGER (= 1 = consulta altos rendimientos)

EF disparado una sola consulta para recuperar los pedidos y clientes con un JOIN.

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

PS: Al recuperar un objeto desde el PP, el objeto se almacena en una memoria caché, mientras que el contexto está activo. En el ejemplo que hice con LAZY LOAD, si todas las 10 órdenes se relacionan con el mismo cliente, verá solo 2 consultas porque cuando le pide a EF que recupere un objeto, el EF verificará si el objeto está en la memoria caché y si encuentra que no disparará otra consulta SQL a la base de datos.

Cuestiones relacionadas