在Entity Framework Core中,可以通过联接表建立many-to-many关系。
我不知道如何以有效的方式查询这样的关系。给定下面的引用关系,我有一个Post
实体,并且PostTags
集合为空。我想加载与Tag
相关的所有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<Tag>
返回到数据库。
这是Relationships - EF Core | Microsoft Docs
中的参考实现class MyContext : DbContext
{
public DbSet<Post> Posts { get; set; }
public DbSet<Tag> Tags { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PostTag>()
.HasKey(t => new { t.PostId, t.TagId });
modelBuilder.Entity<PostTag>()
.HasOne(pt => pt.Post)
.WithMany(p => p.PostTags)
.HasForeignKey(pt => pt.PostId);
modelBuilder.Entity<PostTag>()
.HasOne(pt => pt.Tag)
.WithMany(t => t.PostTags)
.HasForeignKey(pt => pt.TagId);
}
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public List<PostTag> PostTags { get; set; }
}
public class Tag
{
public string TagId { get; set; }
public List<PostTag> PostTags { get; set; }
}
public class PostTag
{
public int PostId { get; set; }
public Post Post { get; set; }
public string TagId { get; set; }
public Tag Tag { get; set; }
}
答案 0 :(得分:3)
如果只需要获取与帖子关联的标签列表,则可以使用简单的投影查询。只需确保以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();
}
如果您确实想将它们加载到传递的Post
实体实例中,则可以通过Query
方法使用显式加载和紧急加载的组合:
void LoadAllTags(Post somePost)
{
await dbContext.Entry(somePost)
.Collection(p => p.PostTags)
.Query()
.Include(pt => pt.Tag)
.LoadAsync();
}