EF Core和最佳加载相关数据

时间:2019-08-21 12:20:52

标签: entity-framework-core

假设我有这样的结构

class User
{
    public List<UserAlbum> Albums;
    ...
}

class Album
{
    ...
}

class UserAlbum
{
    int UserId;
    int AlbumId;

    [ForeignKey("UserId")]
    User user;

    [ForeignKey("AlbumId")]
    Album album;
}

然后我像这样加载我的数据

User user = await Users
    .Include(u => u.UserAlbums).ThenInclude(ua => ua.album)
    // here we have a 9 more similar structures included to User
    .FirstOrDefaultAsync(u => u.Id == user.Id);

这很好。问题在于每个Include()都从Users表中生成查询(如SELECT ... FROM UserAlbums INNER JOIN Users ...中一样)。同样,因为在同一查询中查询了Albums,所以我们无法缓存响应(每个用户都有自己的相册缓存条目)。

因此,假设有10个用户登录,并且我们检索了该用户的所有数据,则总共生成:

  • User表进行110个查询(每个用户11个查询)
  • Albums表的10个查询
  • ...以及我们拥有的每个相似结构的10个查询

因此,使用10个相关数据表,我们有10个用户的210个查询。这可以通过10(用户)+ 100(相关数据)= 120个查询来完成。因此,几乎是实际需要的查询量的两倍!

当然,这可以通过将相关数据与单独的可缓存查询手动组合到表(如专辑)来完成。但这会导致代码混乱,我想知道您如何解决此问题?

2 个答案:

答案 0 :(得分:0)

对于这些查询,我总是使用中间表作为lambda。在这种情况下

(from au in _db.UserAlbums where row.User.Id = "whatever"
select au).Include(ua => ua.Album).Include(ua => ua.User)

我使用sql语法,但应该可以理解。

答案 1 :(得分:0)

我刚刚了解到,当您像这样使用Explicit loading时,不会对User表获得其他查询!

await database.Entry(this).Collection(u => u.albums).Query().Include(a => a.album).LoadAsync();