.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 CoreIQueryable
)开始,而不是物化对象/集合,例如
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();
}