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();
我正在尝试从 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
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();