entity-framework entity-framework-6.1

¿Quieres Entity Framework 6.1 carga ansiosa para cargar solo el primer nivel



entity-framework entity-framework-6.1 (3)

No estoy seguro de que me esté acercando al camino equivocado o es un comportamiento predeterminado, pero no funciona de la manera en que estoy esperando ...

Aquí hay dos clases de muestra ...

public class Person { public string FirstName { get; set; } public string LastName { get; set; } public Department Department { get; set; } }

El segundo es Departamento

public class Department { public string Name { get; set; } public List<Person> People { get; set; } }

Configuración de contexto

public MyDbContext() : base("DefaultConnection") { this.Configuration.ProxyCreationEnabled = false; this.Configuration.LazyLoadingEnabled = false; } public DbSet<Person> People { get; set; } public DbSet<Department> Departments { get; set; }

Trato de cargar personas cuyo apellido es de ''Smith''

var foundPeople = context .people .Where(p => p.LastName == "Smith");

Por encima de la carga de consulta encontrada Personas con solo Nombre y Apellido, sin objeto de Departamento. Es un comportamiento correcto ya que mi LazyLoading está desactivado. Y eso también se esperaba.

Ahora en otra consulta con Eager loading Department,

var foundPeople = context .people .Where(p => p.LastName == "Smith") .Include(p => p.Department);

Por encima de cargas de búsqueda encontradas Personas con Nombre, Apellido, Departamento con Departamento-> Nombre y Departamento-> Personas (todas las personas en ese departamento, que no quiero, solo deseo cargar el primer nivel de la propiedad Incluida).

No sé si esto es un comportamiento intencionado o si cometí un error.

¿Hay alguna manera de simplemente cargar el primer nivel de la propiedad incluida en lugar de completar el gráfico o todos los niveles de la propiedad incluida?


Podría intentar usar una consulta LINQ para que pueda seleccionar solo los campos que necesita. Espero que eso ayude.


Usar Include() para lograr una carga ansiosa solo funciona si la carga diferida está habilitada en tus objetos - es decir, sus propiedades de navegación deben declararse como virtual , de modo que los proxies EF puedan anularlas con el comportamiento de carga diferida. De lo contrario, cargarán ansiosamente automáticamente y Include() no tendrá ningún efecto.

Una vez que declara Person.Department y Department.People como propiedades virtuales , su código debería funcionar como se esperaba.

Lo siento mucho, mi respuesta original fue totalmente incorrecta en general. No leí tu pregunta lo suficiente y de hecho era incorrecta sobre el comportamiento ansioso. No estoy seguro de lo que estaba pensando (¿o quién votó en aumento?). Respuesta real debajo del doblez:

Utilizando el modelo de ejemplo que publicó (con las modificaciones necesarias: claves para las entidades y eliminado " this " del constructor de contexto) no pude reproducir exactamente su problema. Pero no creo que esté haciendo lo que crees que está haciendo.

Cuando carga ansiosamente el Departamento (o carga explícitamente, usando context.Entry(...).Reference(...).Load() ) inspecciona los resultados más de cerca: hay elementos en el Department.People Colecciones de personas, pero no todas las personas, solo las personas que se cargaron en la consulta en sí . Creo que encontrarás, en tu último fragmento, that !foundPeople.SelectMany(p => p.Department.People).Any(p => p.LastName != "Smith") == true . Es decir, ninguno de ellos no es "Smith".

No creo que haya ninguna forma de evitar esto. Entity Framework no está cargando explícita o ansiosamente colecciones People (puede Include(p => p.Department.People) para eso). Solo está vinculando los que se cargaron a su objeto relacionado, debido a la relación circular en el modelo. Además, si hay varias consultas en el mismo contexto que cargan otras personas, también se vincularán en el gráfico de objetos.

(Un lado: en este caso simplificado, las configuraciones de creación de proxy y de carga diferida son superfluas; ninguna de ellas está habilitada en las entidades por el hecho de que ninguna de ellas tiene propiedades perezosas o sustituibles (virtuales): la única cosa Lo hice bien la primera vez.)


Por diseño, DbContext hace lo que se llama "reparación de relaciones". Como su modelo tiene información sobre cuáles son las relaciones entre sus entidades, cada vez que una entidad se adjunta o se modifica en el contexto, EF intentará "arreglar" las relaciones entre las entidades.

Por ejemplo, si carga en el contexto una entidad con un FK que indica que es un elemento secundario de otra entidad ya vinculada al contexto, se agregará a la colección secundaria de la entidad existente. Si realiza cualquier cambio (cambie FK, elimine entidad, etc.) las relaciones se arreglarán automáticamente. Eso es lo que explica la otra respuesta: incluso si carga las entidades relacionadas por separado, con una consulta diferente, se adjuntarán a la colección de elementos secundarios a la que pertenecen.

Esta funcionalidad no puede ser deshabilitada. Ver otras preguntas relacionadas con esto:

Cómo deshacerse de las entidades relacionadas

No sé lo que debe hacer, pero con la versión actual de EF, debe separar la entidad del contexto y eliminar manualmente las entidades relacionadas.

Otra opción es mapear usando AutoMapper o ValueInjecter, para deshacerse de la reparación de la relación.