[英]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. 如果您通过TagId
在PostTags
和Posts
过滤之间应用连接,您将获得所需的列。 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.