c# - Entity Framework 7 中的多对多查询

标签 c# entity-framework entity-framework-core

我正在按照从 http://ef.readthedocs.org/en/latest/modeling/relationships.html 获得的这个示例进行操作

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

现在我的问题是如何构造我的查询以获取给定 TagId 的帖子?像这样的东西:

public List<Post> GetPostsByTagId(int tagId)
{
    //linq query here
}

请记住这是 EF7。

最佳答案

我的第一个建议是将您的集合属性更改为 ICollection<T>而不是 List<T> .您可以在此 post 中找到非常好的解释.

现在回到你真正的问题,这就是我如何处理你的查询:

public List<Post> GetPostsByTadId(int tagId)
{
    using(var context=new MyContext())
    {
      return context.PostTags.Include(p=>p.Post)
                             .Where(pt=> pt.TagId == tagId)
                             .Select(pt=>pt.Post)
                             .ToList();
    }
}

您将需要预加载 Post导航属性,因为 EF7 不支持延迟加载,而且,正如@Igor 在他的解决方案中推荐的那样,您应该包括 PostTags作为 DbSet在您的上下文中:

 public DbSet<PostTags> PostTags { get; set; }

解释:

您的查询开始于 PostTags表,因为在该表中,您可以在其中找到与特定标签相关的所有帖子。查看 Include就像 Post 的内部连接 table 。如果您在 PostTags 之间应用联接和 PostsTagId 过滤,您将获得所需的列。随着Select打电话告诉你只需要 Post 中的列 table 。

如果删除 Include调用,它应该仍然有效。随着Include你明确地告诉你需要做一个连接,但是使用 Select , EF 的 Linq 提供者足够聪明,可以看到它需要隐式地进行连接才能获得 Posts。列作为结果。

关于c# - Entity Framework 7 中的多对多查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36725543/

相关文章:

c# - 我可以声明一个全局变量并从任何地方引用它而不引用它的类吗?

c# - 如何从 char 数组中包含的值初始化一个新的字符串数组?

c# - 来自 c# asmx 的 JSON 返回转义字符串格式而不是 JSON 对象

C# "linking"类

c# - 启用 Animator 会导致闪烁吗?

c# - 由于 InitializedDatabases 列表,EntityFramework6 内存使用量较大,表数量较多

entity-framework - 概念类型的成员数量与对象端类型的成员数量不匹配

c# - Web 应用程序中 Entity Framework 核心可能的内存泄漏

c# - SQL Server 日期时间类型的默认值错误

entity-framework-core - Entity Framework Core OwnsOne 创建单独的表,而不是像预期的那样将属性添加到同一个表