Entity framework core EF核心和最佳加载相关数据

Entity framework core EF核心和最佳加载相关数据,entity-framework-core,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

假设我有一个这样的结构

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()
都会从
用户
表生成一个查询(如
从用户相册中选择…内部加入用户…
)。另外,由于
相册
是在同一查询中查询的,因此我们无法缓存响应(每个用户都有自己的相册缓存条目)

假设有10个用户登录,我们检索用户的所有数据,这总共生成:

  • 110对
    用户
    表的查询(每个用户11个)
  • 对相册的10个查询
  • 。。。对于每个类似的结构,我们有10个查询
因此,有了10个相关数据表,我们就可以为10个用户提供多达210个查询。这可以在10(用户)+100(相关数据)=120个查询中完成。因此,实际需要的查询量几乎增加了一倍


当然,这可以通过手动将相关数据与单独的可缓存查询组合到表(如相册)中来实现。但是这会导致代码混乱,我想知道您是如何处理这个问题的?

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

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

我使用sql语法,但理解起来应该没问题。

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

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

我使用sql语法,但理解起来应该没问题。

我刚刚了解到,当您像这样使用
显式加载
时,您不会得到对用户表的额外查询

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

我刚刚了解到,当您像这样使用
显式加载
时,您不会得到对用户表的额外查询

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

这是什么EF核心版本?使用最新的stable at this time 2.2,有问题的LINQ查询(以及类似的查询)应该总共执行2个SQL查询—一个用于用户数据,一个用于相关的
UserAlbums
Album
,换句话说,与您的自我回答中的显式加载方法相同。这是什么EF核心版本?使用最新版本stable at this time 2.2,所讨论的LINQ查询(以及类似的查询)应该总共执行2个SQL查询—一个用于用户数据,一个用于相关的
用户相册
相册
,换句话说,与您的自我回答中的显式加载方法相同。请参见“
(this)
”,您似乎在
User
类中运行此代码。那么用户如何获得对上下文的引用呢?反转上下文实体关系是一种非常糟糕的反模式。数据库上下文只是传递给用户的方法,我们在其中加载相关实体。是的,我知道这不是很直观,但这是我第一个使用EF Core的项目,我犯了一些错误。代码库很大,并且正在生产中,因此由于时间和金钱的原因,很难进行大的更改。看到“
(this)
”,您似乎在
用户
类中运行此代码。那么用户如何获得对上下文的引用呢?反转上下文实体关系是一种非常糟糕的反模式。数据库上下文只是传递给用户的方法,我们在其中加载相关实体。是的,我知道这不是很直观,但这是我第一个使用EF Core的项目,我犯了一些错误。代码库很大,而且还在生产中,所以由于时间和金钱的原因,很难做出很大的更改。