Deleting a row in the database is handled by the EF Remove() method. This takes a row object as the parameter so we need to know which row to remove and somehow need to load that row. We find the row using the built-in EF method FindAsync() which takes the row ID as a parameter and returns a single row.

The ID is passed in the <form> postback. This is triggered by a submit button in an <a> tag. A hidden <input> tag can be used to pass the ID when the user clicks Delete forcing a <form> postback.

All EF changes are only in memory until the SaveChangesAsync() method is called to persist changes to the database file.

Once all this is done, the Index page needs to refresh and call OnGetAsync() which will load all the rows in the table and display them in the loop. This provides visual confirmation that the deletion was a success.

The edit page in our example has two roles: edit and create. For edit, it displays most or all fields from the current record and allows the user to edit fields in <input> tags. The column names are placed in <label> tags. The ID of the desired record arrives in the URL as a query parameter or URL segment. This ID automatically becomes part of the page model. The OnGetAsync() method accepts the ID as a parameter, makes sure it is not null, and retrieves the matching record with the EF context FindAsync() method. The record is passed to a public member which is referenced in the HTML markup. Since the record can be changed by the user, the [Bind Property] annotation is applied to the member so it can return to the server on <form> post back.

The create mode is similar but uses an empty record as a starting point. Our OnGetAsync() method must check for a value in ID. If it is null, then a new empty member record is created. If it has a value, then FindAsync() is used to retrieve the current row. When the user clicks the Save button, the <form> posts back with a copy of all <input> tag values. The OnPostAsync() again checks for an ID. If it is null, we call the EF method Add(). If the ID has a value, we call Attach() with a chained State value set to Modified. In either case, SaveChangesAsync() must be called to persist the record to the database.

Note that OnPostAsync() returns a Task of IActionResult. This is an ASP.NET trick for redirection. In simpler terms, once the record is saved, we display the Index page with our new or modified record.

Tag helpers are used as attributes of the <label> and <input> tags. The asp-for attribute needs the column name from the record schema so it can bind the column name for the <label> or the record data for the <input>. The helper uses the data type and other information from the EF model to determine which control type to display. This is clearly evident in the Population and UnitedNationsDate fields.


Open Pages/Countries/Index.cshtml.cs and review the code. it uses the same logic as the Continent delete.

Open the file Pages/Countries/Index.cshtml and review the markup. It is similar to what you just added for a Continent.

Test deletion of Continents and Countries.

Open the file Pages/Countries/Edit.cshtml.cs and review the code. It is similar to what you made for Continent.

Open the file Pages/Countries/Edit.cshtml file. The markup uses the same approach with mode fields.

Test editing of Continents and Countries.

Sign up to start coding

Mini Info Outline Icon
By signing up for Codecademy, you agree to Codecademy's Terms of Service & Privacy Policy.

Or sign up using:

Already have an account?