If you've followed the entity framework code first conventions, there are two methods to query "Posts with their Tags"
- The easy way: Use the
virtual ICollection<Tag>
to get the tags of each post.
- Do the (group-)join yourself.
Use the irtual ICollection
Your classes will be similar to the following:
class Post
{
public int Id {get; set;}
... // other properties
// every Post has zero or more Tags (many-to-many)
public virtual ICollection<Tag> Tags {get; set;}
}
class Tag
{
public int Id {get; set;}
... // other properties
// every Tag is used by zero or more Posts (many-to-many)
public virtual ICollection<Post> Posts {get; set;}
}
This is all that entity framework needs to know the many-to-many relation between Posts and Tags. You even don't have to mention the junction table, entity framework will create a standard table for you, and use it whenever needed. Only if you want non-standard names for tables and or columns, you need Attributes or fluent API.
In entity framework, the columns of the tables are represented by the non-virtual properties; the virtual properties represent the relations between the tables (one-to-many, many-to-many, ...)
To get all (or some) Posts, each with all (or some of) their Tables, you can use the virtual ICollection:
var postsWithTheirTags = dbContext.Posts
// only if you don't want all Posts:
.Where(post => ...)
.Select(post => new
{
// Select only the Post properties that you plan to use:
Id = post.Id,
Author = post.Author,
...
Tags = post.Tags.Select(tag => new
{
// again: only the properties that you plan to use
Id = tag.Id,
Text = tag.Text,
...
})
.ToList(),
});
Entity framework knows your relation and will automatically create a Group-join for you using the proper junction table.
This solutions seems to me the most natural one.
Do the GroupJoin yourself
For this you need to have access to the junction table, you'll have to mention it in your dbContext, and use fluent API to tell entity framework that this is the junction table for the many-to-many relation between Posts and Tags.
var postsWithTheirTags = dbContext.Posts.GroupJoin(dbContext.PostTags,
post => post.Id, // from every Post take the primary key
postTag => postTag.PostId // from every PostTag take the foreign key to Post
(post, postTagsOfThisPost) => new
{
// Post properties:
Id = post.Id,
Title = post.Title,
...
Tags = dbContext.Tags.Join(postTagsOfThisPost,
tag => tag.Id // from every Tag take the primary key
postTag => postTag.TagId // from every postTagOfThisPost take the foreign key
(tag, postTagfThisPostAndThisTag) => new
{
Id = tag.Id,
Text = tag.Text,
...
})
.ToList(),
});