Reputation: 53
I am fairly new to the MVC3 framework and am having some issues with editing or creating the data for one of my tables. I used the EF Code first approach in this solution.
I have one table that has 2 fields that link back to the same table. For example: The [entry] table can have a reference to 2 different students. Here is the code for this:
public class Entry
{
public int EntryID { get; set; }
public int DanceEventID { get; set; }
public int StudentID { get; set; }
public int? SecondaryStudentID { get; set; }
public int InstructorID { get; set; }
public int DanceID { get; set; }
public int DanceLevelID { get; set; }
public int StyleID { get; set; }
public int? EntryNumber { get; set; }
public virtual DanceEvent DanceEvent { get; set; }
public virtual Student Student { get; set; }
public virtual Student SecondaryStudent { get; set; }
public virtual Instructor Instructor { get; set; }
public virtual Dance Dance { get; set; }
public virtual DanceLevel DanceLevel { get; set; }
public virtual Style Style { get; set; }
}
public class Student
{
public int StudentID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int DanceLevelID { get; set; }
public virtual DanceLevel DanceLevel { get; set; }
public int StudioID { get; set; }
public virtual Studio Studio { get; set; }
public int GenderID { get; set; }
public virtual Gender Gender { get; set; }
public string FullName
{
get
{
return FirstName + " " + LastName;
}
}
}
The issue that I am having is that when I go to edit or save from the view and I enter a SecondaryStudent, this is not saved. It seems that view is only generating one Student object.
Is this a limitation of MVC3 or more than likely I am just doing something wrong.
EDIT: Here is both the create view and the controller code.
@model HeatBuilder.Models.Entry
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Entry</legend>
<div class="editor-label">
@Html.LabelFor(model => model.DanceEventID, "DanceEvent")
</div>
<div class="editor-field">
@Html.DropDownList("DanceEventID", String.Empty)
@Html.ValidationMessageFor(model => model.DanceEventID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.StudentID, "Student")
</div>
<div class="editor-field">
@Html.DropDownList("StudentID", String.Empty)
@Html.ValidationMessageFor(model => model.StudentID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.StudentID, "Second Student")
</div>
<div class="editor-field">
@Html.DropDownList("StudentID", String.Empty)
@Html.ValidationMessageFor(model => model.SecondaryStudentID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.InstructorID, "Instructor")
</div>
<div class="editor-field">
@Html.DropDownList("InstructorID", String.Empty)
@Html.ValidationMessageFor(model => model.InstructorID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.DanceID, "Dance")
</div>
<div class="editor-field">
@Html.DropDownList("DanceID", String.Empty)
@Html.ValidationMessageFor(model => model.DanceID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.DanceLevelID, "DanceLevel")
</div>
<div class="editor-field">
@Html.DropDownList("DanceLevelID", String.Empty)
@Html.ValidationMessageFor(model => model.DanceLevelID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.StyleID, "Style")
</div>
<div class="editor-field">
@Html.DropDownList("StyleID", String.Empty)
@Html.ValidationMessageFor(model => model.StyleID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using HeatBuilder.Models;
namespace HeatBuilder.Controllers
{
public class EntryController : Controller
{
private HeatBuilderContext db = new HeatBuilderContext();
//
// GET: /Entry/
public ViewResult Index()
{
var entries = db.Entries.Include(e => e.DanceEvent).Include(e => e.Student).Include(e => e.SecondaryStudent).Include(e => e.Instructor).Include(e => e.Dance).Include(e => e.DanceLevel).Include(e => e.Style);
return View(entries.ToList());
}
//
// GET: /Entry/Details/5
public ViewResult Details(int id)
{
Entry entry = db.Entries.Find(id);
return View(entry);
}
//
// GET: /Entry/Create
public ActionResult Create()
{
ViewBag.DanceEventId = new SelectList(db.DanceEvents, "DanceEventId", "EventName");
ViewBag.StudentID = new SelectList(db.Students, "StudentID", "FullName");
ViewBag.SecondaryStudentID = new SelectList(db.Students, "SecondaryStudentID", "FullName");
ViewBag.InstructorId = new SelectList(db.Instructors, "InstructorID", "FullName");
ViewBag.DanceID = new SelectList(db.Dances, "DanceId", "DanceName");
ViewBag.DanceLevelId = new SelectList(db.DanceLevels, "DanceLevelID", "Description");
ViewBag.StyleID = new SelectList(db.Styles, "StyleID", "StyleDescription");
return View();
}
//
// POST: /Entry/Create
[HttpPost]
public ActionResult Create(Entry entry)
{
if (ModelState.IsValid)
{
db.Entries.Add(entry);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DanceEventID = new SelectList(db.DanceEvents, "DanceEventId", "EventName", entry.DanceEventID);
ViewBag.StudentID = new SelectList(db.Students, "StudentID", "FullName", entry.StudentID);
ViewBag.SecondaryStudentID = new SelectList(db.Students, "SecondaryStudentID", "FullName", entry.SecondaryStudentID);
ViewBag.InstructorID = new SelectList(db.Instructors, "InstructorID", "FullName", entry.InstructorID);
ViewBag.DanceID = new SelectList(db.Dances, "DanceId", "DanceName", entry.DanceID);
ViewBag.DanceLevelID = new SelectList(db.DanceLevels, "DanceLevelID", "Description", entry.DanceLevelID);
ViewBag.StyleID = new SelectList(db.Styles, "StyleID", "StyleDescription", entry.StyleID);
return View(entry);
}
//
// GET: /Entry/Edit/5
public ActionResult Edit(int id)
{
Entry entry = db.Entries.Find(id);
ViewBag.DanceEventID = new SelectList(db.DanceEvents, "DanceEventId", "EventName", entry.DanceEventID);
ViewBag.StudentID = new SelectList(db.Students, "StudentID", "FullName", entry.StudentID);
ViewBag.SecondaryStudentID = new SelectList(db.Students, "SecondaryStudentID", "FullName", entry.SecondaryStudentID);
ViewBag.InstructorID = new SelectList(db.Instructors, "InstructorID", "FullName", entry.InstructorID);
ViewBag.DanceID = new SelectList(db.Dances, "DanceId", "DanceName", entry.DanceID);
ViewBag.DanceLevelID = new SelectList(db.DanceLevels, "DanceLevelID", "Description", entry.DanceLevelID);
ViewBag.StyleID = new SelectList(db.Styles, "StyleID", "StyleDescription", entry.StyleID);
return View(entry);
}
//
// POST: /Entry/Edit/5
[HttpPost]
public ActionResult Edit(Entry entry)
{
if (ModelState.IsValid)
{
db.Entry(entry).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DanceEventID = new SelectList(db.DanceEvents, "DanceEventId", "EventName", entry.DanceEventID);
ViewBag.StudentID = new SelectList(db.Students, "StudentID", "FullName", entry.StudentID);
ViewBag.SecondaryStudentID = new SelectList(db.Students, "SecondaryStudentID", "FullName", entry.SecondaryStudentID);
ViewBag.InstructorID = new SelectList(db.Instructors, "InstructorID", "FullName", entry.InstructorID);
ViewBag.DanceID = new SelectList(db.Dances, "DanceId", "DanceName", entry.DanceID);
ViewBag.DanceLevelID = new SelectList(db.DanceLevels, "DanceLevelID", "Description", entry.DanceLevelID);
ViewBag.StyleID = new SelectList(db.Styles, "StyleID", "StyleDescription", entry.StyleID);
return View(entry);
}
//
// GET: /Entry/Delete/5
public ActionResult Delete(int id)
{
Entry entry = db.Entries.Find(id);
return View(entry);
}
//
// POST: /Entry/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
Entry entry = db.Entries.Find(id);
db.Entries.Remove(entry);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
Thanks.
Upvotes: 3
Views: 1117
Reputation: 11
I'm new to this entity model too. But I think what you are referring to a called a self reference. For example an employee may have a field called manager. Now since manager is also an employee the field points back to the the table it's in in this case the employee table. This is a very good question on how to implement it. Maybe create a another table with the it's primary key and a foreign key which can be populated from the manager field in this case to the student table with no other data. This will set up a 1 to 1 relationship if it is allowed. Let me know how you solve this.
Or you can get the secondarly student id with the student id with a request and when it's rendered request again the student id
Upvotes: 0
Reputation: 93444
In your view, you're using StudentID
twice, You should be using SecondaryStudentID
in the second dropdownlist. Also, you are completely using DropDownLists wrong. StudentID
is the currently selected StudentID
from a list of students. You do not assign the SelectList
to StudentID
. You need to create a seperate list of Students, called StudentList or something similar.
ViewBag.ListOfStudents = new SelectList(db.Students, "StudentID", "FullName");
You should probably be using a DropDownListFor.
<div class="editor-label">
@Html.LabelFor(model => model.StudentID, "Student")
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.StudentID, ListOfStudents, "Student")
@Html.ValidationMessageFor(model => model.StudentID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.SecondaryStudentID, "Second Student")
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.SecondaryStudentID, ListOfStudents, String.Empty)
@Html.ValidationMessageFor(model => model.SecondaryStudentID)
</div>
Upvotes: 1
Reputation: 2597
If you are using Code First (so the foreign key relationship isn't taken from the database structure...assuming it exists), and you have an Entity with two different fields, both of which are the foreign key to a second Entity, you can define which Foreign Key to use with each of the child objects. You probably only need this done for the two student objects, but the example below is done for each one of you foreign key relationships:
public class Entry
{
public int EntryID { get; set; }
public int DanceEventID { get; set; }
public int StudentID { get; set; }
public int? SecondaryStudentID { get; set; }
public int InstructorID { get; set; }
public int DanceID { get; set; }
public int DanceLevelID { get; set; }
public int StyleID { get; set; }
public int? EntryNumber { get; set; }
[ForeignKey("DanceEventID")]
public virtual DanceEvent DanceEvent { get; set; }
[ForeignKey("StudentID")]
public virtual Student Student { get; set; }
[ForeignKey("SecondaryStudentID")]
public virtual Student SecondaryStudent { get; set; }
[ForeignKey("InstructorID")]
public virtual Instructor Instructor { get; set; }
[ForeignKey("DanceID")]
public virtual Dance Dance { get; set; }
[ForeignKey("DanceLevelID")]
public virtual DanceLevel DanceLevel { get; set; }
[ForeignKey("StyleID")]
public virtual Style Style { get; set; }
}
Although whether this is causing your problem with data not saving can't be determined for sure.
Upvotes: 1