如何在EF Core中加载关联数据?

时间:2016-07-28 00:41:42

标签: entity-framework asp.net-core entity-framework-core

我有一个Gig模型如下:

public class Gig
{
    public int Id { get; set; }

    [Required]
    public ApplicationUser Artist { get; set; }

    [Required]
    public string ArtistId { get; set; }

    public DateTime DateTime { get; set; }

    [Required]
    [StringLength(255)]
    public string Venue { get; set; }

    [Required]
    public Genre Genre { get; set; }

    [Required]
    public byte GenreId { get; set; }
}

在EF6中,我能够使用以下代码预先加载艺术家流派

            var gigs = _context.Attendances
            .Where(a => a.AttendeeId == userId)
            .Select(a => a.Gig)
            .Include(a => a.Artist)
            .Include(a => a.Genre)
            .ToList();

但是使用EF Core,艺术家信息或流派信息无法加载。 SQL事件探查器显示在投影表上没有调用INNER JOIN。

SELECT [a.Gig].[Id], [a.Gig].[ArtistId], [a.Gig].[DateTime], [a.Gig].[GenreId], [a.Gig].[Venue]
FROM [Attendances] AS [a]
INNER JOIN [Gigs] AS [a.Gig] ON [a].[GigId] = [a.Gig].[Id]
WHERE [a].[AttendeeId] = @__userId_0',N'@__userId_0 nvarchar(450)',@__userId_0=N'469d8515-9a04-46af-9276-09c6fead9e10'

有人可以帮我重写EF Core的查询请包含投影表吗?

eager load

更新: 添加了到db模式脚本here的链接。在这里发布演出表:

CREATE TABLE [dbo].[Gigs](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ArtistId] [nvarchar](450) NOT NULL,
    [DateTime] [datetime2](7) NOT NULL,
    [GenreId] [tinyint] NOT NULL,
    [Venue] [nvarchar](255) NOT NULL,
 CONSTRAINT [PK_Gigs] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[Attendances]  WITH CHECK ADD  CONSTRAINT [FK_Attendances_AspNetUsers_AttendeeId] FOREIGN KEY([AttendeeId])
REFERENCES [dbo].[AspNetUsers] ([Id])
GO
ALTER TABLE [dbo].[Attendances] CHECK CONSTRAINT [FK_Attendances_AspNetUsers_AttendeeId]
GO
ALTER TABLE [dbo].[Attendances]  WITH CHECK ADD  CONSTRAINT [FK_Attendances_Gigs_GigId] FOREIGN KEY([GigId])
REFERENCES [dbo].[Gigs] ([Id])
GO
ALTER TABLE [dbo].[Attendances] CHECK CONSTRAINT [FK_Attendances_Gigs_GigId]
GO
ALTER TABLE [dbo].[Gigs]  WITH CHECK ADD  CONSTRAINT [FK_Gigs_AspNetUsers_ArtistId] FOREIGN KEY([ArtistId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Gigs] CHECK CONSTRAINT [FK_Gigs_AspNetUsers_ArtistId]
GO
ALTER TABLE [dbo].[Gigs]  WITH CHECK ADD  CONSTRAINT [FK_Gigs_Genres_GenreId] FOREIGN KEY([GenreId])
REFERENCES [dbo].[Genres] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Gigs] CHECK CONSTRAINT [FK_Gigs_Genres_GenreId]
GO

Table relationships

1 个答案:

答案 0 :(得分:1)

如果您启用EF Core Logging,您会在日志中看到如下内容:

  

导航的包含操作:' a.Gig.Artist'被忽略,因为在最终查询结果中无法访问目标导航。

a.Gig.Genre类似。

看起来EF Core此时无法处理此类查询的包含(不会从生成的实体开始)。我可以建议的唯一解决方法是重写这样的查询:

var gigs = _context.Gigs
    .Where(g => g.Attendances.Any(a => a.AttendeeId == userId))
    .Include(g => g.Artist)
    .Include(g => g.Genre)
    .ToList();

或者(转换为更好的SQL,尽管SQL执行计划可能是相同的):

var gigs = (from g in _context.Gigs
            from a in g.Attendances
            where a.AttendeeId == userId
            select g)
    .Include(g => g.Artist)
    .Include(g => g.Genre)
    .ToList();