【问题标题】:MVC3 Model View issue with a Model that has 2 foreign keys to the same tableMVC3 模型视图问题,模型具有同一个表的 2 个外键
【发布时间】:2012-01-07 16:11:41
【问题描述】:

我对 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 的限制,还是很可能我只是做错了什么。

编辑: 这是创建视图和控制器代码。

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

谢谢。

【问题讨论】:

  • 你混淆了一些技术。 MVC 与您的持久层无关。请向我们展示您在保存条目时使用的代码。
  • 谢谢。我继续编辑原始帖子以包含控制器代码和创建视图/

标签: asp.net-mvc-3 entity-framework-4 entity-framework-4.1 ef-code-first


【解决方案1】:

在您看来,您使用了两次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>

【讨论】:

    【解决方案2】:

    如果您使用 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; }
    }
    

    虽然无法确定这是否会导致您的数据无法保存。

    【讨论】:

      【解决方案3】:

      我也是这个实体模型的新手。但我认为您所指的是所谓的自我参考。例如,员工可能有一个名为 manager 的字段。现在,由于经理也是员工,因此该字段指向它所在的表,在本例中为员工表。这是一个关于如何实现它的非常好的问题。也许用它的主键和一个外键创建另一个表,在这种情况下可以从经理字段填充到没有其他数据的学生表。如果允许,这将建立一对一的关系。告诉我你是如何解决这个问题的。

      或者您可以通过请求获取带有学生ID的次要学生ID 当它再次呈现请求时,学生ID

      【讨论】:

        猜你喜欢
        • 2010-10-09
        • 1970-01-01
        • 1970-01-01
        • 2013-10-01
        • 1970-01-01
        • 2011-04-13
        • 2013-02-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多