Entity Framework 包含条件而不从包含中选择

Entity Framework Includes with condition without selecting from includes

我正在尝试从 table 中读取 ID,其子 table 满足特定条件。我只需要第一个 table 中的列。我在 c# 的 6.0.2 版本中使用 Microsoft.EntityFrameworkCore。

我稍微简化了数据结构。有一个“架子”,里面有n个“电影”,每个“电影”都有n个“演员”。除了第一个,每个 table 都有一个 ID、一个名称和对其父 table 的引用。 像这样:

Shelves Movies Actors
Id Id Id
Name Name Name
ShelfId MovieId

我使用“代码优先”方法,在我的 DbContext 中,在“OnModelCreating”部分中有以下 DbSet 和它们之间的适当连接:

public DbSet<Shelf> Shelves {get; set; }
public DbSet<Movie> Movies {get; set; }
public DbSet<Actor> Actors {get; set; }


modelBuilder.Entity<Shelf>()
    .HasMany(x => x.Movies)
    .WithOne()
    .IsRequired()
    .OnDelete(DeleteBehavior.Cascade);
    
modelBuilder.Entity<Movie>()
    .HasMany(x => x.Actors)
    .WithOne()
    .IsRequired()
    .OnDelete(DeleteBehavior.Cascade);

我想要的结果是,从演员姓名满足特定条件的架子 table 中获取所有 ID。这个SQL比较简单

SELECT Shelves.Id FROM Shelves
LEFT JOIN Movies ON Shelves.Id = Movies.ShelfId
LEFT JOIN Actors ON Movies.Id = Actors.MovieId
WHERE Actors.Name = 'y'

我试过

var ids = await DbContext.Shelves
                .Include(shelf => shelf.Movies)
                .ThenInclude(movie => movie.Actors.Where(actor => actor.Name == 'x'))
                .ToListAsync();

但是如果我 运行 这个,他只是省略了所有子 table 并且只是在整个“架子”table 上做了一个 select。 我还尝试了很多其他的东西,最后得到了我自己的 DbSet,我通过“FromSqlInterpolated”从中执行上面的 SQL。不好看

Include不是用来查询的,只是用来加载相关实体的。在你的情况下不需要它。

await DbContext.Shelves
    .Where(shelf => shelf.Movies.Any(movie => movie.Actors.Where(actor => actor.Name == 'x').Any()))
    .Select(shelf => shelf.Id)
    .ToListAsync();

或者

await DbContext.Shelves
    .Where(shelf => shelf.Movies.SelectMany(movie => movie.Actors).Any(actor => actor.Name == 'x'))
    .Select(shelf => shelf.Id)
    .ToListAsync();