2011-10-12 26 views
49

si he declarado entidad-relación en mi modelo como virtuales, entonces no hay necesidad de utilizar la instrucción Include en mi consulta LINQ, no ?? -de Entity Framework 4.1 Propiedades virtuales

Por ejemplo: Este es mi clase del modelo :

public class Brand 
{ 
    public int BrandID { get; set; } 
    public string BrandName { get; set; } 
    public string BrandDesc { get; set; } 
    public string BrandUrl { get; set; } 

    public virtual ICollection<Product> Products { get; set; } 
} 

Ahora, para la clase del modelo anterior, no necesito usar el var brandsAndProduct = pe.Brands.Include("Products").Single(brand => brand.BrandID == 22);.

En su lugar, puedo simplemente usar el simple var brandsAndProduct = pe.Brands.Where(brand => brand.BrandID == 22); y tendré automáticamente la entidad relacionada disponible cuando se acceda.

¿Es correcto en mi comprensión?

Además, dígame en qué situaciones preferiría una sobre la otra ??

Respuesta

158

Tiene razón, pero la regla es más compleja para que realmente funcione como se esperaba. Si define su propiedad de navegación virtual EF creará en tiempo de ejecución una nueva clase (proxy dinámico) derivada de su clase Brand y la usará en su lugar. Esta nueva clase creada dinámicamente contiene lógica para cargar la propiedad de navegación cuando se accede por primera vez. Esta característica se denomina carga diferida (o mejor carga lenta transparente).

Qué reglas se deben satisfacer para hacer este trabajo:

  • Todas las propiedades de navegación en categoría deben ser virtual
  • creación de proxy dinámico no debe estar desactivado (context.Configuration.ProxyCreationEnabled). Está habilitado por defecto.
  • La carga diferida no se debe deshabilitar (context.Configuration.LazyLoadingEnabled). Está habilitado por defecto.
  • Se debe adjuntar entidad (por defecto si carga entidad de la base de datos) al contexto y el contexto no se debe eliminar = la carga diferida solo funciona dentro del contexto de vida utilizado para cargarlo desde la base de datos (o donde se adjuntó entidad proxy)

Lo opuesto a la carga diferida se denomina carga ansiosa y eso es lo que hace Include. Si usa Include, su propiedad de navegación se carga junto con la entidad principal.

El uso de la carga diferida y la carga ansiosa depende de sus necesidades y también del rendimiento. Include carga todos los datos en la consulta de una única base de datos, pero puede dar como resultado huge data set cuando se usa mucho incluir o cargar muchas entidades. Si está seguro de que necesitará Brand y todo Products para procesarlo, debe utilizar la carga ansiosa.

La carga diferida se utiliza a su vez si no está seguro de la propiedad de navegación que necesitará. Por ejemplo, si carga 100 marcas, solo deberá acceder a productos de una marca, no es necesario cargar productos para todas las marcas en la consulta inicial. La desventaja de la carga diferida es la consulta separada (ida y vuelta de la base de datos) para cada propiedad de navegación => si carga 100 marcas sin incluir y tendrá acceso a la propiedad Products en cada instancia Brand su código generará otras 100 consultas para poblar estas propiedades de navegación = ansioso la carga usaría solo la consulta singe pero la carga diferida usó 101 consultas (se llama problema N + 1).

En escenarios más complejos, puede encontrar que ninguna de estas estrategias funciona como necesita y puede utilizar una tercera estrategia llamada carga explícita o consultas separadas para cargar marcas y productos para todas las marcas que necesita.

carga explícita tiene desventajas similares a carga lenta pero hay que activar manualmente:

context.Entry(brand).Collection(b => b.Products).Load(); 

Las principales ventajas para la carga explícita es filtrar relación. Puede usar Query() antes de Load() y usar cualquier filtrado o incluso carga ansiosa de relaciones anidadas.

+3

Siento que esta respuesta es concisa y completa ... Gracias. Referido "Cargando datos relacionados" http://msdn.microsoft.com/en-us/magazine/hh205756.aspx – Lijo

+0

Gracias por su respuesta. Todavía me ayuda en 2016. Y tengo una pregunta más: ¿Hay alguna manera de hacer siempre ansioso cargar todas las propiedades en una sola llamada? Dado que hay algunas situaciones que los modelos que tiene múltiples propiedades de navegación y deben cargarse cada vez. – anuith

Cuestiones relacionadas