2012-01-10 18 views
9

Spiacente, il titolo non è più specifico - non sapevo come descriverlo in modo sintetico. I miei viaggi e la posizione hanno una relazione molti-a-molti - semplice, tranne che le località non hanno bisogno di sapere dei viaggi che li usano. Ho creato queste entità per rappresentare questo:Entity Framework - caricamento entusiasmante delle entità correlate

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 
} 

posso ottenere il viaggio a carico ansiosi è TripLocations ma non riesco a ottenere i TripLocations per caricare desiderosi loro posizioni. Ho provato un sacco di combinazioni di configurazione fluente e "Include" ING nella query come

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

Tutti i suggerimenti molto apprezzati!

+0

cosa è 'ride'? – tyron

+0

Scusa dovrebbe essere "viaggio" – gruve

+0

Perché hai l'entità 'TripLocation' nel tuo modello? Ci sono altre proprietà in questa entità che non stai mostrando? Altrimenti puoi rimuovere questa entità dal tuo modello e creare una relazione molti-a-molti direttamente tra 'Trip' e' Location'. Nel tuo attuale modello hai effettivamente due relazioni uno-a-molti e non molti-a-molti. – Slauma

risposta

14

Ho ricreato il tuo scenario qui e sono riuscito a ottenere tutti i risultati in una singola query.

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

Questo è tutto. Questo è ciò che è stato interrogato contro la mia base di dati:

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 

UPDATE:

Se si vuole mantenere la versione lambda, questo farà il lavoro:

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

Maggiori informazioni sul MSDN blog .

+0

Grazie! La tua risposta mi ha confermato che ero sulla strada giusta e mi ha permesso di guardare il codice reale da una prospettiva diversa (l'esempio sopra è proprio quello che pensavo fossero le parti rilevanti del codice reale). – gruve

+1

Grazie per l'equivalente lambda. – angularsen

0

Per quanto riguarda l'espressione lambda, è possibile utilizzare context.Set come @tyron ha detto o è possibile utilizzare context.Trips. Per esempio:

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

Per fare questo lavoro di codice, è necessario definire una proprietà di tipo DbSet nella classe DbContext come di seguito:

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

Definizione di una proprietà che restituisce DbSet è bello, ma allo stesso tempo è equivalente all'accessing context.Set. È solo uno stile di codice che potrebbe anche essere combinato.

0

Rimuovere la parola chiave VIRTUAL sulle proprietà della relazione e.g.Location, che disabiliterà il caricamento pigro e ti costringerà a caricare con interesse.

Problemi correlati