【问题标题】:Entity Framework Core many-to-many navigation issuesEntity Framework Core 多对多导航问题
【发布时间】:2017-09-30 08:24:18
【问题描述】:

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 });
}

我从其他示例中遗漏了什么?

【问题讨论】:

  • 也许尝试删除对 base.OnModelCreating 的调用?覆盖 OnModelCreating 时我从未打过电话
  • 你试过包括.Include(p =&gt; p.PhotoTags)吗? EF Core 没有延迟加载,因此您必须通过 include 或 .Load() 显式进行预先加载
  • @Tseng 如果你使用PhotoTags.Select(p =&gt; p.Tags),EF 知道它必须包含 PhotoTags,这与延迟加载不同
  • @CamiloTerevinto:我知道它是在选择时执行的(因为它是一个投影),但不确定它是否在 SelectMany 上执行
  • @Tseng SelectMany 是双 Select 语句的快捷方式,所以是的。我对SelectSelectMany 有非常复杂的查询,而没有Include 调用

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


【解决方案1】:

事实上,这并不是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);

【讨论】:

  • 啊,我刚刚意识到,看着你的回答,OP 没有以_context 开头这句话...
猜你喜欢
  • 1970-01-01
  • 2020-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
相关资源
最近更新 更多