实体框架核心多对多导航问题

时间:2017-05-02 17:50:10

标签: c# entity-framework asp.net-core .net-core entity-framework-core

实体框架核心尚未实现多对多关系,正如GitHub问题#1368中所追踪的那样;但是,当我按照该问题中的导航示例或Stack Overflow中的similar answers时,我的枚举无法产生结果。

我在照片和标签之间有多对多的关系。

实现连接表后,示例显示我应该能够:

var tags = photo.PhotoTags.Select(p => p.Tag);

虽然没有结果,但我可以通过以下方式加载:

var tags = _context.Photos
    .Where(p => p.Id == 1)
    .SelectMany(p => p.PhotoTags)
    .Select(j => j.Tag)
    .ToList();

相关代码:

public class Photo
{
    public int Id { get; set; }
    public virtual ICollection<PhotoTag> PhotoTags { get; set; }
}

public class Tag
{
    public int Id { get; set; }
    public virtual ICollection<PhotoTag> PhotoTags { get; set; }
}

public class PhotoTag
{
    public int PhotoId { get; set; }
    public Photo Photo { get; set; }

    public int TagId { get; set; }
    public Tag Tag { get; set; }
}

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.Entity<PhotoTag>().HasKey(x => new { x.PhotoId, x.TagId });
}

我在其他例子中缺少什么?

1 个答案:

答案 0 :(得分:4)

事实上,这不是many-to-many关系的具体内容,但通常是因为EF Core中缺少延迟加载支持。因此,为了填充Tag属性,必须急切(或明确)加载它。所有这些(有点)都在EF Core文档的Loading Related Data部分中进行了解释。如果您查看包含多个级别部分,您会看到以下说明

  

您可以使用ThenInclude方法深入了解关系以包含多个级别的相关数据。以下示例加载所有博客,相关帖子以及每篇帖子的作者。

和加载Post.Author的示例与您的几乎相同:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
            .ThenInclude(post => post.Author)
        .ToList();
}

所以要使这个工作

var tags = photo.PhotoTags.Select(p => p.Tag);

应使用以下内容检索photo变量:

var photo = _context.Photos
   .Include(e => e.PhotoTags)
       .ThenInclude(e => e.Tag)
   .FirstOrDefault(e => e.Id == 1);