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.