Entity Framework - готовая загрузка связанных объектов - PullRequest
9 голосов
/ 10 января 2012

Извините, название не является более конкретным - я не знал, как описать это кратко. У меня есть Поездки и Местоположение, которые имеют отношение многие ко многим - просто, за исключением того, что Местам не нужно знать о Поездках, которые их используют. Я создал эти объекты, чтобы представить это:

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
}

Я могу получить Trip to eager, чтобы загрузить его TripLocations, но я не могу заставить TripLocations загружать их Locations. Я пробовал несколько комбинаций быстрой конфигурации и включения в запрос, таких как

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

Любые предложения очень ценятся!

Ответы [ 3 ]

14 голосов
/ 10 января 2012

Я воссоздал ваш сценарий здесь и смог получить все результаты в одном запросе.

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

Вот и все. Вот что было запрошено в моей базе данных:

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:

Если вы хотите сохранить лямбда-версию, это сработает:

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

Дополнительная информация в блоге MSDN .

0 голосов
/ 13 июля 2016

Удалите ключевое слово VIRTUAL в свойствах ваших отношений, например, Местоположение, которое отключит отложенную загрузку и вынуждает вас активно загружать.

0 голосов
/ 04 июня 2014

Что касается лямбда-выражения, вы можете использовать context.Set, как сказал @tyron, или вы можете использовать context.Trips. Например:

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

Чтобы этот код работал, вам нужно определить свойство типа DbSet в вашем классе DbContext, как показано ниже:

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

Определение свойства, которое возвращает DbSet, приятно, но в то же время эквивалентно доступу к context.Set. Это просто стиль кода, который также можно комбинировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...