MVC3 Model View проблема с моделью, которая имеет 2 внешних ключа к одной таблице - PullRequest
3 голосов
/ 07 января 2012

Я довольно плохо знаком с платформой MVC3 и у меня возникли некоторые проблемы с редактированием или созданием данных для одной из моих таблиц.Я использовал первый подход кода EF в этом решении.

У меня есть одна таблица, в которой есть 2 поля, которые ссылаются на одну и ту же таблицу.Например: таблица [entry] может содержать ссылку на 2 разных ученика.Вот код для этого:

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;
        }
    }
}

Проблема, с которой я сталкиваюсь, заключается в том, что когда я иду к редактированию или сохранению из вида и вводю SecondaryStudent, это не сохраняется.Кажется, что представление генерирует только один объект Student.

Является ли это ограничением MVC3 или более чем вероятно, я просто делаю что-то не так.

EDIT: Воти представление создания, и код контроллера.

@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);
    }
}
}

Спасибо.

Ответы [ 3 ]

1 голос
/ 07 января 2012

По вашему мнению, вы используете StudentID дважды, вы должны использовать SecondaryStudentID во втором выпадающем списке. Кроме того, вы полностью используете DropDownLists неправильно. StudentID в настоящее время выбрано StudentID из списка студентов. Вы не назначаете SelectList на StudentID. Вам необходимо создать отдельный список студентов, который называется StudentList или что-то подобное.

ViewBag.ListOfStudents = new SelectList(db.Students, "StudentID", "FullName"); 

Возможно, вам следует использовать 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>
1 голос
/ 07 января 2012

Если вы используете Code First (то есть отношение внешнего ключа не берется из структуры базы данных ... при условии, что оно существует), и у вас есть объект с двумя различными полями, оба из которых являются внешним ключом для Второй объект, вы можете определить, какой внешний ключ использовать с каждым из дочерних объектов. Возможно, вам нужно сделать это только для двух объектов ученика, но приведенный ниже пример сделан для каждого из ваших отношений внешнего ключа:

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; }
}

Хотя причина этого в том, что данные не сохраняются, точно определить невозможно.

0 голосов
/ 07 июля 2012

Я тоже новичок в этой модели сущностей. Но я думаю, то, что вы имеете в виду, называется ссылкой на себя. Например, у сотрудника может быть поле, называемое менеджером. Теперь, поскольку менеджер также является сотрудником, поле указывает на таблицу, в которой он находится, в данном случае на таблицу сотрудников. Это очень хороший вопрос о том, как это реализовать. Возможно, создайте другую таблицу с ее первичным ключом и внешним ключом, который в этом случае может быть заполнен из поля менеджера в таблицу ученика без других данных. Это установит отношения 1 к 1, если это разрешено. Дайте мне знать, как вы решите это.

Или вы можете получить вторичный идентификатор студента с идентификатором студента с запросом и когда он отдает запрос снова, студенческий идентификатор

...