.net 在EF Core中对多对多关系执行有效查询

.net 在EF Core中对多对多关系执行有效查询,.net,entity-framework,.net-core,entity-framework-core,.net,Entity Framework,.net Core,Entity Framework Core,在实体框架核心中,可以通过连接表建立关系 我不知道如何有效地查询这样的关系。根据下面的引用关系,我有一个Post实体,PostTags集合为空。我想加载所有与Post相关联的标记,目前为止,我所拥有的最好的东西如下所示: void GetAllTags(Post somePost) { await dbContext.Entry(somePost) .Collection(p => p.PostTags) .LoadAsync(); fore

在实体框架核心中,可以通过连接表建立关系

我不知道如何有效地查询这样的关系。根据下面的引用关系,我有一个
Post
实体,
PostTags
集合为空。我想加载所有与
Post
相关联的
标记,目前为止,我所拥有的最好的东西如下所示:

void GetAllTags(Post somePost)
{
    await dbContext.Entry(somePost)
        .Collection(p => p.PostTags)
        .LoadAsync();
    foreach(var postTag in somePost.PostTags)
    {
        await dbContext.Entry(postTag)
            .Reference(p => p.Tag)
            .LoadAsync();
    }
}
我真的更愿意通过一个查询向数据库返回一个
ICollection


这是来自的参考实现

class MyContext:DbContext
{
公共DbSet Posts{get;set;}
公共DbSet标记{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasKey(t=>new{t.PostId,t.TagId});
modelBuilder.Entity()
.HasOne(pt=>pt.Post)
.WithMany(p=>p.PostTags)
.HasForeignKey(pt=>pt.posted);
modelBuilder.Entity()
.HasOne(pt=>pt.Tag)
.WithMany(t=>t.posttag)
.HasForeignKey(pt=>pt.TagId);
}
}
公营职位
{
公共int PostId{get;set;}
公共字符串标题{get;set;}
公共字符串内容{get;set;}
公共列表PostTags{get;set;}
}
公共类标签
{
公共字符串TagId{get;set;}
公共列表PostTags{get;set;}
}
公共类PostTag
{
公共int PostId{get;set;}
公共Post Post{get;set;}
公共字符串TagId{get;set;}
公共标记{get;set;}
}
如果您只需要获取与帖子相关联的标签列表,您可以使用简单的投影查询。只需确保从一个
DbSet
(即EF Core
IQueryable
)开始,而不是物化对象/集合,例如

ICollection<Tag> GetAllTags(Post somePost)
{
    return await dbContext.Set<PostTag>()
        .Where(pt => pt.PostId == somePost.PostId)
        .Select(pt => pt.Tag)
        .ToListAsync();
}

为什么我需要从dbSet开始?我提出了一个
dbContext.Entry(somePost).Collection(p=>p.PostTags).Query().Include(j=>j.Tag).然后Include(t=>t.someOtherFKProp).选择(j=>j.Tag)
进行查询(通过递归连接到第三个表)。这会失败吗?这是另一种方法-
.Entry(…).Collection(…).Query()
提供了与我使用的
Set()相同的
IQueryable
。区别在于
DbSet
方法不需要上下文附加(跟踪)
somePost
,而
Entry(somePost)
肯定会将
somePost
附加到上下文。
ICollection<Tag> GetAllTags(Post somePost)
{
    return await dbContext.Set<PostTag>()
        .Where(pt => pt.PostId == somePost.PostId)
        .Select(pt => pt.Tag)
        .ToListAsync();
}
void LoadAllTags(Post somePost)
{
    await dbContext.Entry(somePost)
        .Collection(p => p.PostTags)
        .Query()
        .Include(pt => pt.Tag)
        .LoadAsync();
}