2010-09-08 28 views
12

Estoy utilizando Entity Framework 4 con MVC y necesito asegurarme de que cualquier entidad referenciada que quiero usar en mi vista haya sido cargada antes de que regrese el método del controlador, de lo contrario la vista escupe el temido:Entity Framework - Ansioso de cargar entidades relacionadas

La instancia de ObjectContext se ha eliminado y ya no se puede usar para las operaciones que requieren una conexión.

Al seleccionar directamente desde el contexto, sólo puede utilizar el método Include(string) para obligarlos a ser incluidos en la consulta SQL generada:

var sellers = context.Sellers.Include("Recommendations.User").ToList(); 

Sin embargo, si tengo (por ejemplo) un ayudante método que acepta una entidad y necesita que todos los elementos se carguen, no hay un método Include disponible.

void Test(Seller seller) 
{ 
    // ensure all recommendations and their users are loaded 
} 

El método de fuerza bruta es colocar a través de ellos:

foreach (var recommendation in seller.Recommendations) 
    recommendation.User.ToString(); // just force a load 

Si tengo 100 recomendaciones, esto creará 101 consultas SQL detrás de las escenas. Idealmente, quiero un método/enfoque que cargue todos los objetos Recommendation Y User con un solo viaje a SQL.

Muéstrame el dinero.

EDIT No estoy realmente interesado en discutir si esta es una arquitectura buena o mala. He simplificado mi escenario por el bien de la pregunta. ¿Puedes hacer lo que estoy pidiendo con la API de EF?

EDITAR 2

Ladislav's edit ofrecido esperanza de un nuevo enfoque, pero parece que no soy muy allá.

que puedo lograr lo que quiero a través de este:

context.Sellers.Include("Recommendations.User").Single(s => s.Id == seller.Id); 

Este enfoque no funciona usando LoadProperty ...

context.LoadProperty(seller, "Recommendations.User"); 

... a medida que se produce el error ...

No se encontró la propiedad de navegación especificada Recommendations.User.

Ninguno de estos enfoques funciona si no tiene una referencia al contexto.

+0

Si bien esto no responde a su pregunta (por lo tanto, la publico como un comentario), sí analiza la carga de entidades relacionadas ya que actualmente funciona en EF6. También este es el primer enlace SOF que aparece en Google cuando se buscan "entidades relacionadas con la carga del marco de trabajo de la entidad": http://msdn.microsoft.com/en-us/data/jj574232. Así que pensé en compartir ... . –

Respuesta

3

Creo que este es un trabajo para su repositorio que, en su caso, debe exponer métodos como GetFullSeller (todas las propiedades cargadas por Include) y GetSeller (única entidad base).

Editar:

Hay varias maneras de cómo cargar las propiedades de navegación en EF v4.

No hay carga automática.

+1

¿Eso significa que solo trabajaría en un objeto que provenga directamente de un repositorio? ¿Qué sucede si recibe una entidad sobre, por ejemplo, WCF, y luego desea adjuntarla y completar más campos para hacer más transformaciones antes de guardarla? De todos modos, realmente no veo esto como una cuestión de arquitectura. Solo quiero saber si la API admite esto, y si no, ¿por qué no? –

0

En lugar de pasar sus objetos de dominio reales (EntityObject s) a la vista, puede usar su controlador para asignarlos a un objeto Model que represente mejor lo que su vista debería mostrar. Esto reducirá la cantidad de lógica requerida en su Vista, y tendrá el agradable efecto secundario de evitar pasar EntityObjects después de que su contexto haya expirado.

Editar basado en tu edición:

No, la API no tiene manera de tomar un solo objeto Entidad y hacer que todos los demás objetos de entidad de su tipo que se cargó al mismo tiempo que era estar vagamente poblado con una propiedad en particular de una sola vez. Es mejor que saque todos los artículos en primer lugar usando la mención Include como la que muestra en su pregunta.

+0

gracias por su respuesta. He simplificado mi caso en aras de la claridad en la pregunta. De hecho, utilizo un 'modelo de vista' de modo que casi no hay ninguna lógica en mis puntos de vista. Mi modelo está profundamente interrelacionado con las relaciones y no quiero recrear esa jerarquía en los modelos de vista, por lo que tengo un modelo de vista de nivel base que tiene algunas enumeraciones de entidades en ellos. En mi caso, necesito desreferenciar a otra entidad sobre los enumerados. Esta no es realmente una pregunta de arquitectura, sino una API. –

+0

según su edición;) Eso no es exactamente lo que quiero hacer. Tengo un vendedor. Necesito que se carguen todas las recomendaciones del vendedor. En cada una de esas recomendaciones, necesito que se cargue el usuario correspondiente. No necesito que se carguen otros vendedores. –

+0

Si pudiera inventar la API, diría 'seller.Load (" Recommendations.User ")', del mismo modo que podría hacerlo en la consulta del conjunto de entidades original (como en OP.) –

2

Estoy en la misma situación. Creo que con EF es muy fácil caer en un problema de consulta de 101.

Una solución puede ser crear una clase parcial de su clase Vendedor (generada por EF) e implementar un GetSubclassNameQ que devuelva un IQueryable, y un GetSubclassNameQFull que devuelva un IQueryable con carga ansiosa.

public partial class Seller{ 

    public IQueryable<Recommendation> GetRecommendationsQ(EntityContainer entitycontainer) { 
    return entitycontainer.Recommendations; 
    }  

    public IQueryable<Recommendation> GetRecommendationsQFull(EntityContainer entitycontainer) { 
    return this.GetRecommendationsQ(entitycontainer).Include("Recommendations.User"); 
    } 

    public IQueryable<Recommendation> GetRecommendationsQ() { 
    return GetRecommendationsQ(new EntityContainer()); 
    } 

    public IQueryable<Recommendation> GetRecommendationsQFull() { 
    return this.GetRecommendationsQ().Include("Recommendations.User"); 
    } 

} 
5

Ésta es una cuestión de edad, pero en EF6 se puede llevar a cabo la carga de objetos dependientes de una entidad como this:

context.Entry(seller).Collection(s => s.Recommendations).Query().Include(r => r.User)).Load(); 

Eso sería cargar todos Recommendations y su relacionada Users para la dada seller

Cuestiones relacionadas