entity-framework - 如何在 EF Core 中预加载关联数据?

标签 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 中,我能够使用以下代码预先加载 ArtistGenre

            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

更新: 添加了指向数据库模式脚本的链接 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

最佳答案

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

The Include operation for navigation: 'a.Gig.Artist' was ignored because the target navigation is not reachable in the final query results.

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();

关于entity-framework - 如何在 EF Core 中预加载关联数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38625383/

相关文章:

c# - 过滤 IQueryable 子列表

c# - 添加依赖注入(inject)后,Add-Migration 出现错误

.net - GraphQL 热巧克力构造函数 DI 在第二次请求时失败

entity-framework - 用于多对多关系的实体 Sql

asp.net-mvc - 带有 EF 的自定义成员提供程序

ASP.NET核心: Dependencies: Latest Versions

asp.net-core - NET Core BitBucket管道构建失败-当我拥有.csproj时需要project.json

database - EF Core - 对同一个表的多个引用

entity-framework - 仅使用 DbSet 更新对象

c# - 如何在 ASP.NET Core 中将我的服务注册拆分成不同的文件?