Some Setup
Before introducing many-to-many relationships in EntityFrameworkCore, we need to add a new model and view to our app.
The starter code for this chapter is located within the orm-one-to-many branch .
In this section, we explore how we can work with many-to-many relationships in ASP.NET using EntityFrameworkCore. To do so, we need a class that we can relate to Event
in a many-to-many fashion. This is the Tag
class.
The Tag
Model Class
Between the last section and this one, we have added a new persistent model class to the code, Tag
. This class represents a tag of the type used for blog or social media posts. For us, a tag will be a topical label that can be applied to any event. Thus, we’ll eventually relate Event
and Tag
to each other in a many-to-many way.
The steps to add this code follow the exact same process that we used to add a persistent EventCategory class , so we won’t go through them in detail here.
The Detail
View
Before working with tags, we will add a new view, along with the corresponding controller, ViewModel, and template. The new view will live at the route /Events/Detail/X
, where X
is the ID of a specific event. This view will display the details of a specific event on its own page.
Adding a Detail
view for events is relatively straightforward, but it also involves a couple of new concepts. We’ll start by creating a ViewModel to model the data we want to display in the view.
|
|
The model replicates the Name
, Description
, and Email
properties of Event
while storing Category.Name
as a string. This is a minor variant of the Event
class, but by the end of this section we’ll add more behavior to EventDetailViewModel
that will make the benefits of using a ViewModel in this case more clear.
Within EventsController
we add a handler method to display the view.
|
|
There are two new concepts to introduce here. First, our method takes a parameter named id
. You have worked with such parameters in the past, as query parameters mapped to method parameters. For example, we could reach this handler with the request path /Events/Detail?id=X
. What’s new now is that we will use the same parameter mapping, but with a path parameter. A path parameter is a parameter that is part of the request path. In this case, we will be able to make requests to a path like Events/Detail/X
.
This parameter mapping works seamlessly because the of default path template specified in the Program.cs
file.
|
|
This template is "{controller=Home}/{action=Index}/{id?}"
. The last portion, {id?}
, means that any path parameter following the action method will map to a method parameter named id
.
If we wanted to use a different URL structure, or a different method parameter name, we would need to include additional configuration. See the documentation on routing for more details.
The other new concept here is the use of the EF method Single
:
|
|
This method takes a boolean lambda expression and filters the Context.Events
collection down to the one event that satisfies e.Id == id
. In other words, it finds the single event with Id
matching the path parameter.
We use Single
instead of Find
here because we also need to call Include
to eagerly fetch the Category
property. Include
can not be chained with Find
.
The only remaining task is to create the view for the new event details. It should consist of a table displaying the properties of the Event
. Create a new file within the /Views/Events
folder named Detail.cshtml
and add the following code:
|
|
That wraps up this section. In the next chapter we will create the many-to-many
relationship between the Event
and Tag
class.