Skip to content Skip to sidebar Skip to footer

Uploading Validating and Sorting a File Into Database Using Ef in Asp.net Mvc5

Skip to primary content

In the previous tutorial you displayed related information. In this tutorial you'll update related data. For most relationships, this can be done by updating either foreign key fields or navigation backdrop. For many-to-many relationships, the Entity Framework doesn't expose the join table directly, so you add and remove entities to and from the appropriate navigation properties.

The following illustrations show some of the pages that you'll piece of work with.

Course_create_page

Instructor_edit_page_with_courses

Instructor edit with courses

In this tutorial, y'all:

  • Customize courses pages
  • Add part to instructors page
  • Add courses to instructors page
  • Update DeleteConfirmed
  • Add together function location and courses to the Create page

Prerequisites

  • Reading Related Data

Customize courses pages

When a new course entity is created, it must have a relationship to an existing department. To facilitate this, the scaffolded code includes controller methods and Create and Edit views that include a driblet-down list for selecting the department. The drop-down list sets the Grade.DepartmentID foreign key property, and that's all the Entity Framework needs in society to load the Department navigation property with the appropriate Department entity. Y'all'll use the scaffolded code, only change information technology slightly to add mistake handling and sort the drop-downwardly listing.

In CourseController.cs, delete the four Create and Edit methods and replace them with the following code:

              public ActionResult Create() {     PopulateDepartmentsDropDownList();     return View(); }  [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "CourseID,Championship,Credits,DepartmentID")]Course course) {     try     {         if (ModelState.IsValid)         {             db.Courses.Add(course);             db.SaveChanges();             return RedirectToAction("Index");         }     }     catch (RetryLimitExceededException /* dex */)     {         //Log the error (uncomment dex variable name and add a line here to write a log.)         ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, come across your system administrator.");     }     PopulateDepartmentsDropDownList(course.DepartmentID);     return View(course); }  public ActionResult Edit(int? id) {     if (id == naught)     {         return new HttpStatusCodeResult(HttpStatusCode.BadRequest);     }     Form grade = db.Courses.Find(id);     if (grade == null)     {         render HttpNotFound();     }     PopulateDepartmentsDropDownList(course.DepartmentID);     return View(class); }  [HttpPost, ActionName("Edit")] [ValidateAntiForgeryToken] public ActionResult EditPost(int? id) {     if (id == null)     {         return new HttpStatusCodeResult(HttpStatusCode.BadRequest);     }     var courseToUpdate = db.Courses.Observe(id);     if (TryUpdateModel(courseToUpdate, "",        new cord[] { "Title", "Credits", "DepartmentID" }))     {         try         {             db.SaveChanges();              return RedirectToAction("Alphabetize");         }         catch (RetryLimitExceededException /* dex */)         {             //Log the error (uncomment dex variable proper name and add a line here to write a log.             ModelState.AddModelError("", "Unable to save changes. Try over again, and if the problem persists, see your system ambassador.");         }     }     PopulateDepartmentsDropDownList(courseToUpdate.DepartmentID);     return View(courseToUpdate); }  individual void PopulateDepartmentsDropDownList(object selectedDepartment = goose egg) {     var departmentsQuery = from d in db.Departments                            orderby d.Name                            select d;     ViewBag.DepartmentID = new SelectList(departmentsQuery, "DepartmentID", "Proper name", selectedDepartment); }                          

Add the following using statement at the outset of the file:

              using System.Data.Entity.Infrastructure;                          

The PopulateDepartmentsDropDownList method gets a list of all departments sorted by name, creates a SelectList collection for a drop-down list, and passes the drove to the view in a ViewBag property. The method accepts the optional selectedDepartment parameter that allows the calling lawmaking to specify the detail that volition exist selected when the drop-down list is rendered. The view volition pass the name DepartmentID to the DropDownList helper, and the helper then knows to look in the ViewBag object for a SelectList named DepartmentID.

The HttpGet Create method calls the PopulateDepartmentsDropDownList method without setting the selected item, because for a new grade the department is non established yet:

              public ActionResult Create() {     PopulateDepartmentsDropDownList();     render View(); }                          

The HttpGet Edit method sets the selected item, based on the ID of the section that is already assigned to the course beingness edited:

              public ActionResult Edit(int? id) {     if (id == null)     {         return new HttpStatusCodeResult(HttpStatusCode.BadRequest);     }     Course course = db.Courses.Find(id);     if (course == naught)     {         return HttpNotFound();     }     PopulateDepartmentsDropDownList(form.DepartmentID);     return View(course); }                          

The HttpPost methods for both Create and Edit also include code that sets the selected item when they redisplay the page after an error:

              grab (RetryLimitExceededException /* dex */) {     //Log the error (uncomment dex variable proper name and add a line hither to write a log.)     ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your organisation administrator."); } PopulateDepartmentsDropDownList(course.DepartmentID); render View(course);                          

This code ensures that when the page is redisplayed to show the fault message, any department was selected stays selected.

The Course views are already scaffolded with drop-down lists for the section field, but you don't want the DepartmentID caption for this field, so make the following highlighted modify to the Views\Course\Create.cshtml file to alter the explanation.

              @model ContosoUniversity.Models.Form  @{     ViewBag.Title = "Create"; }  <h2>Create</h2>  @using (Html.BeginForm())  {     @Html.AntiForgeryToken()          <div class="form-horizontal">         <h4>Course</h4>         <hr />         @Html.ValidationSummary(true)          <div class="class-group">             @Html.LabelFor(model => model.CourseID, new { @class = "control-label col-md-2" })             <div grade="col-md-10">                 @Html.EditorFor(model => model.CourseID)                 @Html.ValidationMessageFor(model => model.CourseID)             </div>         </div>          <div form="class-group">             @Html.LabelFor(model => model.Title, new { @class = "command-label col-physician-two" })             <div class="col-md-x">                 @Html.EditorFor(model => model.Title)                 @Html.ValidationMessageFor(model => model.Championship)             </div>         </div>          <div class="form-group">             @Html.LabelFor(model => model.Credits, new { @grade = "control-characterization col-dr.-2" })             <div course="col-doctor-ten">                 @Html.EditorFor(model => model.Credits)                 @Html.ValidationMessageFor(model => model.Credits)             </div>         </div>          <div class="class-group">             <characterization class="control-label col-md-2" for="DepartmentID">Department</label>             <div class="col-md-10">                 @Html.DropDownList("DepartmentID", String.Empty)                 @Html.ValidationMessageFor(model => model.DepartmentID)             </div>         </div>          <div class="form-group">             <div class="col-md-offset-2 col-md-10">                 <input type="submit" value="Create" class="btn btn-default" />             </div>         </div>     </div> }  <div>     @Html.ActionLink("Back to List", "Alphabetize") </div>  @section Scripts {     @Scripts.Render("~/bundles/jqueryval") }                          

Make the same change in Views\Course\Edit.cshtml.

Normally the scaffolder doesn't scaffold a main cardinal because the cardinal value is generated by the database and can't be changed and isn't a meaningful value to be displayed to users. For Course entities the scaffolder does include an text box for the CourseID field because information technology understands that the DatabaseGeneratedOption.None attribute means the user should exist able enter the primary primal value. But it doesn't empathise that considering the number is meaningful you want to see information technology in the other views, and then you demand to add it manually.

In Views\Form\Edit.cshtml, add together a course number field earlier the Title field. Because it'southward the main key, it's displayed, simply it can't exist inverse.

              <div form="class-group">     @Html.LabelFor(model => model.CourseID, new { @class = "command-label col-doc-2" })     <div class="col-doctor-10">         @Html.DisplayFor(model => model.CourseID)     </div> </div>                          

At that place's already a hidden field (Html.HiddenFor helper) for the course number in the Edit view. Adding an Html.LabelFor helper doesn't eliminate the need for the hidden field because information technology doesn't crusade the class number to be included in the posted data when the user clicks Salve on the Edit page.

In Views\Course\Delete.cshtml and Views\Grade\Details.cshtml, alter the department name caption from "Name" to "Section" and add a course number field before the Title field.

              <dt>     Department </dt>  <dd>     @Html.DisplayFor(model => model.Department.Name) </dd>  <dt>     @Html.DisplayNameFor(model => model.CourseID) </dt>  <dd>     @Html.DisplayFor(model => model.CourseID) </dd>                          

Run the Create page (brandish the Grade Index page and click Create New) and enter information for a new grade:

Value Setting
Number Enter grand.
Championship Enter Algebra.
Credits Enter 4.
Department Select Mathematics.

Click Create. The Class Index page is displayed with the new grade added to the list. The section name in the Index page list comes from the navigation property, showing that the relationship was established correctly.

Run the Edit page (display the Course Index page and click Edit on a course).

Modify information on the page and click Save. The Form Index page is displayed with the updated course data.

Add together office to instructors page

When yous edit an teacher record, y'all want to be able to update the instructor's office assignment. The Teacher entity has a i-to-zero-or-i relationship with the OfficeAssignment entity, which means you must handle the following situations:

  • If the user clears the office assignment and information technology originally had a value, you must remove and delete the OfficeAssignment entity.
  • If the user enters an office assignment value and it originally was empty, you must create a new OfficeAssignment entity.
  • If the user changes the value of an role consignment, you must change the value in an existing OfficeAssignment entity.

Open up InstructorController.cs and look at the HttpGet Edit method:

              {     if (id == null)     {         return new HttpStatusCodeResult(HttpStatusCode.BadRequest);     }     Teacher instructor = db.Instructors.Discover(id);     if (instructor == null)     {         return HttpNotFound();     }     ViewBag.ID = new SelectList(db.OfficeAssignments, "InstructorID", "Location", instructor.ID);     return View(teacher); }                          

The scaffolded code here isn't what y'all want. It's setting up data for a drib-down listing, but you what you need is a text box. Replace this method with the following lawmaking:

              public ActionResult Edit(int? id) {     if (id == null)     {         render new HttpStatusCodeResult(HttpStatusCode.BadRequest);     }     Instructor instructor = db.Instructors         .Include(i => i.OfficeAssignment)         .Where(i => i.ID == id)         .Single();     if (teacher == null)     {         render HttpNotFound();     }     return View(instructor); }                          

This code drops the ViewBag statement and adds eager loading for the associated OfficeAssignment entity. You tin't perform eager loading with the Find method, so the Where and Single methods are used instead to select the instructor.

Supplant the HttpPost Edit method with the post-obit code. which handles role assignment updates:

              [HttpPost, ActionName("Edit")] [ValidateAntiForgeryToken] public ActionResult EditPost(int? id) {     if (id == zilch)     {         render new HttpStatusCodeResult(HttpStatusCode.BadRequest);     }     var instructorToUpdate = db.Instructors        .Include(i => i.OfficeAssignment)        .Where(i => i.ID == id)        .Single();      if (TryUpdateModel(instructorToUpdate, "",        new string[] { "LastName", "FirstMidName", "HireDate", "OfficeAssignment" }))     {        try        {           if (String.IsNullOrWhiteSpace(instructorToUpdate.OfficeAssignment.Location))           {              instructorToUpdate.OfficeAssignment = null;           }            db.SaveChanges();            return RedirectToAction("Index");        }        catch (RetryLimitExceededException /* dex */)       {          //Log the mistake (uncomment dex variable name and add together a line here to write a log.          ModelState.AddModelError("", "Unable to salve changes. Try once more, and if the problem persists, see your system administrator.");       }    }    return View(instructorToUpdate); }                          

The reference to RetryLimitExceededException requires a using statement; to add it - hover your mouse over RetryLimitExceededException. The following message appears:  Retry exception message

Select Show potential fixes, so using System.Information.Entity.Infrastructure

Resolve Retry exception

The code does the following:

  • Changes the method proper noun to EditPost because the signature is now the aforementioned as the HttpGet method (the ActionName attribute specifies that the /Edit/ URL is all the same used).

  • Gets the current Instructor entity from the database using eager loading for the OfficeAssignment navigation belongings. This is the same every bit what you did in the HttpGet Edit method.

  • Updates the retrieved Instructor entity with values from the model binder. The TryUpdateModel overload used enables you to whitelist the backdrop you want to include. This prevents over-posting, as explained in the second tutorial.

                      if (TryUpdateModel(instructorToUpdate, "",       new cord[] { "LastName", "FirstMidName", "HireDate", "OfficeAssignment" }))                                  
  • If the office location is blank, sets the Instructor.OfficeAssignment belongings to null so that the related row in the OfficeAssignment table will exist deleted.

                      if (String.IsNullOrWhiteSpace(instructorToUpdate.OfficeAssignment.Location)) {     instructorToUpdate.OfficeAssignment = cipher; }                                  
  • Saves the changes to the database.

In Views\Instructor\Edit.cshtml, after the div elements for the Rent Date field, add a new field for editing the part location:

              <div form="form-grouping">     @Html.LabelFor(model => model.OfficeAssignment.Location, new { @class = "command-characterization col-medico-two" })     <div course="col-md-10">         @Html.EditorFor(model => model.OfficeAssignment.Location)         @Html.ValidationMessageFor(model => model.OfficeAssignment.Location)     </div> </div>                          

Run the page (select the Instructors tab and and then click Edit on an instructor). Change the Part Location and click Save.

Add courses to instructors page

Instructors may teach any number of courses. At present you'll enhance the Instructor Edit page by adding the ability to change class assignments using a group of bank check boxes.

The relationship between the Course and Instructor entities is many-to-many, which means you exercise non have direct access to the foreign primal properties which are in the join tabular array. Instead, you add together and remove entities to and from the Teacher.Courses navigation belongings.

The UI that enables you to change which courses an instructor is assigned to is a group of check boxes. A check box for every grade in the database is displayed, and the ones that the instructor is currently assigned to are selected. The user can select or clear cheque boxes to change course assignments. If the number of courses were much greater, yous would probably want to use a unlike method of presenting the information in the view, simply you'd utilise the same method of manipulating navigation properties in order to create or delete relationships.

To provide information to the view for the list of check boxes, you'll utilize a view model form. Create AssignedCourseData.cs in the ViewModels binder and supersede the existing code with the following lawmaking:

              namespace ContosoUniversity.ViewModels {     public class AssignedCourseData     {         public int CourseID { get; set; }         public string Title { become; set; }         public bool Assigned { get; set; }     } }                          

In InstructorController.cs, replace the HttpGet Edit method with the following code. The changes are highlighted.

              public ActionResult Edit(int? id) {     if (id == null)     {         return new HttpStatusCodeResult(HttpStatusCode.BadRequest);     }     Instructor instructor = db.Instructors         .Include(i => i.OfficeAssignment)         .Include(i => i.Courses)         .Where(i => i.ID == id)         .Unmarried();     PopulateAssignedCourseData(instructor);     if (instructor == nada)     {         return HttpNotFound();     }     return View(instructor); }  private void PopulateAssignedCourseData(Instructor instructor) {     var allCourses = db.Courses;     var instructorCourses = new HashSet<int>(instructor.Courses.Select(c => c.CourseID));     var viewModel = new List<AssignedCourseData>();     foreach (var course in allCourses)     {         viewModel.Add(new AssignedCourseData         {             CourseID = form.CourseID,             Title = grade.Championship,             Assigned = instructorCourses.Contains(course.CourseID)         });     }     ViewBag.Courses = viewModel; }                          

The code adds eager loading for the Courses navigation property and calls the new PopulateAssignedCourseData method to provide information for the check box array using the AssignedCourseData view model class.

The code in the PopulateAssignedCourseData method reads through all Course entities in guild to load a list of courses using the view model form. For each course, the lawmaking checks whether the course exists in the teacher'south Courses navigation property. To create efficient lookup when checking whether a course is assigned to the teacher, the courses assigned to the instructor are put into a HashSet collection. The Assigned property is set to true for courses the instructor is assigned. The view volition use this property to determine which check boxes must be displayed as selected. Finally, the list is passed to the view in a ViewBag property.

Next, add the code that'due south executed when the user clicks Save. Replace the EditPost method with the following code, which calls a new method that updates the Courses navigation property of the Teacher entity. The changes are highlighted.

              [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit(int? id, string[] selectedCourses) {     if (id == aught)     {         return new HttpStatusCodeResult(HttpStatusCode.BadRequest);     }     var instructorToUpdate = db.Instructors        .Include(i => i.OfficeAssignment)        .Include(i => i.Courses)        .Where(i => i.ID == id)        .Single();      if (TryUpdateModel(instructorToUpdate, "",        new cord[] { "LastName", "FirstMidName", "HireDate", "OfficeAssignment" }))     {         attempt         {             if (String.IsNullOrWhiteSpace(instructorToUpdate.OfficeAssignment.Location))             {                 instructorToUpdate.OfficeAssignment = null;             }              UpdateInstructorCourses(selectedCourses, instructorToUpdate);              db.SaveChanges();              render RedirectToAction("Index");         }         catch (RetryLimitExceededException /* dex */)         {             //Log the error (uncomment dex variable name and add a line here to write a log.             ModelState.AddModelError("", "Unable to save changes. Try again, and if the trouble persists, run across your system ambassador.");         }     }     PopulateAssignedCourseData(instructorToUpdate);     return View(instructorToUpdate); } private void UpdateInstructorCourses(cord[] selectedCourses, Instructor instructorToUpdate) {    if (selectedCourses == null)    {       instructorToUpdate.Courses = new List<Grade>();       return;    }      var selectedCoursesHS = new HashSet<string>(selectedCourses);    var instructorCourses = new HashSet<int>        (instructorToUpdate.Courses.Select(c => c.CourseID));    foreach (var course in db.Courses)    {       if (selectedCoursesHS.Contains(course.CourseID.ToString()))       {          if (!instructorCourses.Contains(course.CourseID))          {             instructorToUpdate.Courses.Add together(course);          }       }       else       {          if (instructorCourses.Contains(course.CourseID))          {             instructorToUpdate.Courses.Remove(course);          }       }    } }                          

The method signature is now different from the HttpGet Edit method, then the method proper name changes from EditPost back to Edit.

Since the view doesn't have a collection of Grade entities, the model binder tin't automatically update the Courses navigation holding. Instead of using the model folder to update the Courses navigation holding, you'll do that in the new UpdateInstructorCourses method. Therefore you need to exclude the Courses property from model bounden. This doesn't require any change to the lawmaking that calls TryUpdateModel because y'all're using the whitelisting overload and Courses isn't in the include list.

If no check boxes were selected, the code in UpdateInstructorCourses initializes the Courses navigation property with an empty collection:

              if (selectedCourses == null) {     instructorToUpdate.Courses = new List<Course>();     return; }                          

The lawmaking then loops through all courses in the database and checks each course against the ones currently assigned to the instructor versus the ones that were selected in the view. To facilitate efficient lookups, the latter two collections are stored in HashSet objects.

If the check box for a grade was selected but the form isn't in the Instructor.Courses navigation property, the form is added to the collection in the navigation property.

              if (selectedCoursesHS.Contains(form.CourseID.ToString())) {     if (!instructorCourses.Contains(course.CourseID))     {         instructorToUpdate.Courses.Add(course);     } }                          

If the bank check box for a course wasn't selected, merely the course is in the Instructor.Courses navigation holding, the grade is removed from the navigation property.

              else {     if (instructorCourses.Contains(form.CourseID))     {         instructorToUpdate.Courses.Remove(course);     } }                          

In Views\Teacher\Edit.cshtml, add a Courses field with an assortment of check boxes by adding the following code immediately after the div elements for the OfficeAssignment field and before the div element for the Save push:

              <div class="form-grouping">     <div class="col-md-kickoff-ii col-md-x">         <table>             <tr>                 @{                     int cnt = 0;                     List<ContosoUniversity.ViewModels.AssignedCourseData> courses = ViewBag.Courses;                      foreach (var course in courses)                     {                         if (cnt++ % three == 0)                         {                             @:</tr><tr>                         }                         @:<td>                             <input type="checkbox"                                proper name="selectedCourses"                                value="@course.CourseID"                                @(Html.Raw(course.Assigned ? "checked=\"checked\"" : "")) />                                @course.CourseID @:  @form.Title                         @:</td>                     }                     @:</tr>                 }         </table>     </div> </div>                          

After you lot paste the lawmaking, if line breaks and indentation don't expect like they exercise hither, manually fix everything so that it looks like what y'all see hither. The indentation doesn't take to be perfect, but the @</tr><tr>, @:<td>, @:</td>, and @</tr> lines must each be on a single line as shown or you'll get a runtime fault.

This code creates an HTML tabular array that has three columns. In each cavalcade is a cheque box followed by a caption that consists of the course number and title. The check boxes all have the same name ("selectedCourses"), which informs the model binder that they are to be treated as a group. The value attribute of each check box is set to the value of CourseID. When the page is posted, the model binder passes an array to the controller that consists of the CourseID values for just the cheque boxes which are selected.

When the check boxes are initially rendered, those that are for courses assigned to the instructor have checked attributes, which selects them (displays them checked).

After changing course assignments, you lot'll want to exist able to verify the changes when the site returns to the Index page. Therefore, you demand to add a column to the tabular array in that page. In this case yous don't need to use the ViewBag object, because the data you lot want to display is already in the Courses navigation belongings of the Instructor entity that you're passing to the page every bit the model.

In Views\Teacher\Index.cshtml, add a Courses heading immediately post-obit the Office heading, as shown in the post-obit instance:

              <tr>      <thursday>Last Name</th>      <th>First Name</th>      <th>Rent Appointment</thursday>      <th>Function</thursday>     <thursday>Courses</thursday>     <thursday></th>  </tr>                          

Then add a new item jail cell immediately following the function location detail cell:

              <td>     @if (item.OfficeAssignment != nix)     {         @detail.OfficeAssignment.Location     } </td> <td>     @{         foreach (var class in detail.Courses)         {             @form.CourseID @:  @course.Championship <br />         }     } </td> <td>     @Html.ActionLink("Select", "Index", new { id = item.ID }) |     @Html.ActionLink("Edit", "Edit", new { id = item.ID }) |     @Html.ActionLink("Details", "Details", new { id = particular.ID }) |     @Html.ActionLink("Delete", "Delete", new { id = particular.ID }) </td>                          

Run the Teacher Index folio to meet the courses assigned to each instructor.

Click Edit on an instructor to run across the Edit page.

Modify some course assignments and click Save. The changes you make are reflected on the Index page.

Note: The arroyo taken here to edit instructor grade information works well when in that location is a limited number of courses. For collections that are much larger, a unlike UI and a different updating method would be required.

Update DeleteConfirmed

In InstructorController.cs, delete the DeleteConfirmed method and insert the following code in its place.

              [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(int id) {    Instructor instructor = db.Instructors      .Include(i => i.OfficeAssignment)      .Where(i => i.ID == id)      .Single();     db.Instructors.Remove(instructor);      var department = db.Departments         .Where(d => d.InstructorID == id)         .SingleOrDefault();     if (department != null)     {         department.InstructorID = null;     }     db.SaveChanges();    return RedirectToAction("Index"); }                          

This lawmaking makes the following change:

  • If the instructor is assigned as ambassador of whatsoever section, removes the instructor assignment from that department. Without this code, you would get a referential integrity mistake if you tried to delete an instructor who was assigned as administrator for a department.

This code doesn't handle the scenario of one instructor assigned every bit administrator for multiple departments. In the last tutorial you lot'll add code that prevents that scenario from happening.

Add function location and courses to the Create folio

In InstructorController.cs, delete the HttpGet and HttpPost Create methods, and then add the following code in their place:

              public ActionResult Create() {     var instructor = new Instructor();     teacher.Courses = new List<Course>();     PopulateAssignedCourseData(instructor);     return View(); }  [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "LastName,FirstMidName,HireDate,OfficeAssignment" )]Instructor teacher, string[] selectedCourses) {     if (selectedCourses != null)     {         teacher.Courses = new List<Class>();         foreach (var class in selectedCourses)         {             var courseToAdd = db.Courses.Find(int.Parse(course));             instructor.Courses.Add(courseToAdd);         }     }     if (ModelState.IsValid)     {         db.Instructors.Add together(instructor);         db.SaveChanges();         return RedirectToAction("Alphabetize");     }     PopulateAssignedCourseData(instructor);     return View(instructor); }                          

This lawmaking is similar to what you saw for the Edit methods except that initially no courses are selected. The HttpGet Create method calls the PopulateAssignedCourseData method not because there might be courses selected but in order to provide an empty drove for the foreach loop in the view (otherwise the view lawmaking would throw a null reference exception).

The HttpPost Create method adds each selected class to the Courses navigation property before the template code that checks for validation errors and adds the new teacher to the database. Courses are added even if at that place are model errors so that when in that location are model errors (for an example, the user keyed an invalid date) so that when the page is redisplayed with an error message, any course selections that were made are automatically restored.

Find that in order to be able to add courses to the Courses navigation property you have to initialize the holding every bit an empty collection:

              instructor.Courses = new List<Course>();                          

Every bit an alternative to doing this in controller code, you could do it in the Instructor model by changing the belongings getter to automatically create the collection if it doesn't exist, as shown in the following example:

              individual ICollection<Form> _courses; public virtual ICollection<Course> Courses  {      get     {         return _courses ?? (_courses = new List<Class>());     }     set     {         _courses = value;     }  }                          

If you modify the Courses property in this manner, you can remove the explicit property initialization code in the controller.

In Views\Instructor\Create.cshtml, add together an office location text box and course bank check boxes after the rent appointment field and earlier the Submit push.

              <div course="form-group">     @Html.LabelFor(model => model.OfficeAssignment.Location, new { @class = "command-characterization col-md-2" })     <div class="col-md-10">         @Html.EditorFor(model => model.OfficeAssignment.Location)         @Html.ValidationMessageFor(model => model.OfficeAssignment.Location)     </div> </div>  <div grade="form-group">     <div class="col-medico-offset-two col-md-10">         <table>             <tr>                 @{                     int cnt = 0;                     List<ContosoUniversity.ViewModels.AssignedCourseData> courses = ViewBag.Courses;                      foreach (var grade in courses)                     {                         if (cnt++ % 3 == 0)                         {                             @:</tr><tr>                         }                         @:<td>                             <input type="checkbox"                                name="selectedCourses"                                value="@form.CourseID"                                @(Html.Raw(course.Assigned ? "checked=\"checked\"" : "")) />                                @grade.CourseID @:  @course.Title                         @:</td>                     }                     @:</tr>                 }         </table>     </div> </div>                          

After you paste the code, fix line breaks and indentation equally you did before for the Edit page.

Run the Create page and add together an instructor.

Handling transactions

Every bit explained in the Basic Grime Functionality tutorial, by default the Entity Framework implicitly implements transactions. For scenarios where you demand more control -- for example, if yous want to include operations done exterior of Entity Framework in a transaction -- run across Working with Transactions on MSDN.

Get the code

Download the Completed Project

Additional resources

Links to other Entity Framework resource can be constitute in ASP.Cyberspace Data Access - Recommended Resource.

Next step

In this tutorial, you:

  • Customized courses pages
  • Added office to instructors folio
  • Added courses to instructors page
  • Updated DeleteConfirmed
  • Added part location and courses to the Create page

Accelerate to the next commodity to learn how to implement an asynchronous programming model.

seaypeturber.blogspot.com

Source: https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application

Post a Comment for "Uploading Validating and Sorting a File Into Database Using Ef in Asp.net Mvc5"