实体框架 - 渴望加载相关实体

时间:2012-01-10 16:26:21

标签: entity-framework ef-code-first eager-loading

对不起标题不是更具体 - 我不知道如何简洁地描述。 我有Trips和Location有多对多的关系 - 直截了当,除了Locations不需要知道使用它们的Trips。我创建了这些实体来表示:

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之前加载它的TripLocations,但我无法让TripLocations急切加载他们的位置。我尝试了一些流畅的配置组合和“包含”在查询中,如

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

任何建议都非常感谢!

3 个答案:

答案 0 :(得分:14)

我在这里重新创建了你的场景,我能够在一次查询中获得所有结果。

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

<强>更新

如果您想保留lambda版本,这将完成工作:

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

有关MSDN blog的更多信息。

答案 1 :(得分:0)

关于lambda表达式,你可以使用context.Set像@tyron说的那样,或者你可以使用context.Trips。例如:

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

为了使这段代码有效,你需要在DbContext类中定义类型为DbSet的属性,如下所示:

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

定义返回DbSet的属性很不错,但同时它等同于访问context.Set。它只是一种代码风格,也可以合并。

答案 2 :(得分:0)

删除关系属性egLocation上的VIRTUAL关键字,这将禁用延迟加载并强制您急切加载。