2012-01-10 611 views
9

Lo siento, el título no es más específico, no supe cómo describir esto de manera sucinta. Tengo viajes y ubicaciones que tienen una relación de varios a varios: sencillo, excepto que las ubicaciones no tienen necesidad de conocer los viajes que los utilizan. He creado estas entidades para representar esto:Entity Framework - carga ansiosa de entidades relacionadas

public class Trip 
{ 
    public int TripId { get; set; } 
    public virtual IList<TripLocation> TripLocations { get; set; } 
} 

public class TripLocation 
{ 
    public int TripId { get; set; } 
    public int LocationId { get; set; } 

    public virtual Location Location { get; set; } 
} 

public class Location 
{ 
    public int LocationId { get; set; } 
    // Note: Intentionally no collection of Trips 
} 

puedo conseguir el viaje a la carga ansiosa es TripLocations pero no puedo conseguir los TripLocations a la carga ansiosa sus ubicaciones. He intentado un montón de combinaciones de configuración fluida e "Incluir" ing en la consulta como

IQueryable<Trip> query = from trip in context 
           .Include(r =>r.TripLocations) 
           .Include(r => r.TripLocations.Select(tl => tl.Location)) 
         select ride; 

¡Todas las sugerencias son muy apreciadas!

+0

¿Qué es 'ride'? – tyron

+0

Lo siento debería haber sido "viaje" – gruve

+0

¿Por qué tiene la entidad 'TripLocation' en su modelo? ¿Hay otras propiedades en esta entidad que no se muestran? De lo contrario, puede eliminar esta entidad de su modelo por completo y crear una relación de muchos a muchos directamente entre 'Trip' y' Location'. En su modelo actual, en realidad tiene dos relaciones uno a muchos y no muchos a muchos. – Slauma

Respuesta

14

He recreado su escenario aquí y pude obtener todos los resultados en una sola consulta.

var a = from trip in context.Trips.Include("TripLocations.Location") 
     select trip; 

Eso es todo. Eso es lo que se preguntó en contra de mi base de datos:

SELECT 
[Project1].[TripId] AS [TripId], 
[Project1].[Name] AS [Name], 
[Project1].[C1] AS [C1], 
[Project1].[TripId1] AS [TripId1], 
[Project1].[LocationId] AS [LocationId], 
[Project1].[LocationId1] AS [LocationId1], 
[Project1].[Name1] AS [Name1] 
FROM (SELECT 
    [Extent1].[TripId] AS [TripId], 
    [Extent1].[Name] AS [Name], 
    [Join1].[TripId] AS [TripId1], 
    [Join1].[LocationId1] AS [LocationId], 
    [Join1].[LocationId2] AS [LocationId1], 
    [Join1].[Name] AS [Name1], 
    CASE WHEN ([Join1].[TripId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1] 
    FROM [dbo].[Trips] AS [Extent1] 
    LEFT OUTER JOIN (SELECT [Extent2].[TripId] AS [TripId], [Extent2].[LocationId] AS [LocationId1], [Extent3].[LocationId] AS [LocationId2], [Extent3].[Name] AS [Name] 
     FROM [dbo].[TripLocations] AS [Extent2] 
     INNER JOIN [dbo].[Locations] AS [Extent3] ON [Extent2].[LocationId] = [Extent3].[LocationId]) AS [Join1] ON [Extent1].[TripId] = [Join1].[TripId] 
) AS [Project1] 
ORDER BY [Project1].[TripId] ASC, [Project1].[C1] ASC 

ACTUALIZACIÓN:

Si quieres mantener con la versión lambda, esto va a hacer el trabajo:

IQueryable<Trip> query = from ride in context.Set<Trip>() 
          .Include(t=>t.TripLocations.Select(l=>l.Location))          
         select ride; 

Más información sobre el MSDN blog .

+0

¡Gracias! Su respuesta confirmó que estaba en el camino correcto y me hizo mirar el código real desde una perspectiva diferente (el ejemplo anterior es justo lo que pensé que son las partes relevantes del código real). – gruve

+1

Gracias por el equivalente lambda. – angularsen

0

En cuanto a la expresión lambda, puede usar context.Set como dijo @tyron o puede usar context.Trips. Por ejemplo:

IQueryable<Trip> query = from ride in context.Trips 
          .Include(t=>t.TripLocations.Select(l=>l.Location))          
         select ride; 

Con el fin de hacer este trabajo de código, es necesario definir una propiedad de tipo DbSet en su clase DbContext, como a continuación:

public DbSet<Trip> Trips { get; set; } 

Definición de una propiedad que devuelve DbSet es agradable, pero al mismo tiempo, es equivalente a acceder al contexto. Conjunto. Es solo un estilo de código que también podría combinarse.

0

Elimine la palabra clave VIRTUAL en sus propiedades de relación, por ejemplo, Ubicación, que inhabilitará la Carga diferida y lo forzará a una carga ansiosa.

Cuestiones relacionadas