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个查询
当然,这可以通过手动将相关数据与单独的可缓存查询组合到表(如相册)中来实现。但是这会导致代码混乱,我想知道您是如何处理这个问题的?对于这些查询,我总是使用中间表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的项目,我犯了一些错误。代码库很大,而且还在生产中,所以由于时间和金钱的原因,很难做出很大的更改。