简体   繁体   English

实体框架7中的多对多查询

[英]Many-to-many query in Entity Framework 7

I am following this example which I got from http://ef.readthedocs.org/en/latest/modeling/relationships.html 我正在关注这个我从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; }
}

Now my question is how would I construct my query to get posts given TagId? 现在我的问题是如何构建我的查询以获得TagId的帖子? Something like: 就像是:

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

Please keep in mind this is EF7. 请记住这是EF7。

My first advice is change your collection properties to ICollection<T> instead of List<T> . 我的第一个建议是将您的集合属性更改为ICollection<T>而不是List<T> You can find a really good explanation in this post . 你可以在这篇文章中找到一个非常好的解释。

Now going back to your real problem, this is how I would do your query: 现在回到你真正的问题,我会这样做你的查询:

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

You will need to eager load Post navigation property because EF7 doesn't support lazy loading, and also, as @Igor recommended in his solution, you should include PostTags as a DbSet in your context: 你需要急于加载Post导航属性,因为EF7不支持延迟加载,而且,正如@Igor在他的解决方案中推荐的那样,你应该在你的上下文中包含PostTags作为DbSet

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

Explanation: 说明:

Your query start in PostTags table because is in that table where you can find all the post related with an specific tag. 您的查询从PostTags表开始,因为在该表中您可以找到与特定标记相关的所有帖子。 See the Include like a inner join with Post table. 请参阅Include如内部联接和Post表。 If you apply a join between PostTags and Posts filtering by TagId , you will get the columns that you need. 如果您通过TagIdPostTagsPosts过滤之间应用连接,您将获得所需的列。 With the Select call you are telling you only need the columns from Post table. 使用Select调用,您只需要Post表中的列。

If you remove the Include call, it should still work. 如果您删除Include呼叫,它仍然可以工作。 With the Include you're telling explicitly that you need to do a join, but with the Select , the Linq provider of EF is smart enough to see it needs to do implicitly a join to get the Posts columns as result. 使用Include你明确告诉你需要进行连接,但是使用Select ,EF的Linq提供者足够聪明,可以看到它需要隐式地进行连接以获得Posts列作为结果。

db.Posts.Where(post => post.PostTags.Any(pt => pt.TagId == tagId));

This is not really specific to EF7. 这并不是EF7特有的。

You could extend your DbContext to include PostTags 您可以扩展您的DbContext以包含PostTags

class MyContext : DbContext
{
    public DbSet<PostTags> PostTags { get; set; }

Then your query 然后你的查询

db.Posts.Where(post => db.PostTags.Any(pt => pt.PostId == post.PostId && pt.TagId == tagId))
.Select(post => post);

include theinclude both works fine... but only problem is intellisense not identifying or showing the methods just type and then proceed all works fine ... 包括两个工作正常...但只有问题是intellisense没有识别或显示方法只是键入,然后进行所有工作正常...

            var res = await _context.Diseases.Include(x => x.Disease2Symptom)
            .ThenInclude(z => z.Symptom).ToListAsync();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM