EntityFramework_MVC4中EF5 新手入门教程之六 ---6.通过 Entity Framework 更新关联数据
2015-02-05 17:19
525 查看
在前面的教程中,您将显示相关的数据 ;在本教程中,您会更新相关的数据。对于大多数的关系,这个目标是可以通过更新相应的外键字段来达到的。对于多对多关系,实体框架并不直接,暴露联接表,因此您必须显式添加和删除,并从相应的导航属性的实体。
下面的插图显示页面,您将利用工作。
在CourseController.cs,删除四个
此代码可确保当要显示错误消息,重新显示页上,不管部入选始终保持选定状态。
在Views\Course\Create.cshtml,添加突出显示的代码,以创建一个新的课程编号字段在标题字段之前。正如解释在早些时候的教程中,主键字段不搭建在默认情况下,但此主键是有意义的所以您希望用户能够输入的密钥值。
@Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Credits)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Credits)
@Html.ValidationMessageFor(model => model.Credits)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.DepartmentID, "Department")
</div>
<div class="editor-field">
@Html.DropDownList("DepartmentID", String.Empty)
@Html.ValidationMessageFor(model => model.DepartmentID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}[/code]
在Views\Course\Edit.cshtml、 Views\Course\Delete.cshtml、 Views\Course\Details.cshtml添加课程数字字段在Title字段之前。因为它是主键,它会显示,但不能更改。
运行创建页 (显示路线索引页面,并单击新建) 和输入一门新课程的数据:
单击创建。课程索引页面显示添加到列表中的新课程。在索引页面列表中的部门名称来自于导航属性,显示正确建立了关系。
运行编辑页 (显示路线索引页面,并在课程上单击编辑)。
更改页面上的数据并单击保存。课程索引页显示已更新的课程数据。
如果用户清除办公室分配,它原本的价值,您必须删除并删除
如果用户输入的办公室分配值,它最初为空,您必须创建一个新的
如果用户更改办公室被分配的值,则必须更改现有的
打开InstructorController.cs ,然后看看
这里搭建的代码不是你想要什么。它设置数据为下拉列表,但你你所需要的是一个文本框。此方法替换为以下代码:
这段代码滴
用以下代码替换
该代码执行以下任务:
获取从数据库使用的当前的
从模型联编程序的值更新检索到的
如果办公室位置为空,将设置
将更改保存到数据库中。
在Views\Instructor\Edit.cshtml后
运行该页面 (选择教官选项卡,然后点击编辑讲师)。更改办公地点并单击保存.
用户界面中,使您能够更改哪些课程的讲师是分配给是一组复选框。显示数据库中的每一门课程的复选框,并选择了那些讲师当前分配给。用户可以选择或清除复选框以更改课程作业。如果课程数目大得多,你可能想要使用不同的方法,在视图中,显示数据,但您将使用相同的方法操纵导航属性以创建或删除关系。
为列表中的复选框提供数据到视图,您将使用一个视图模型类。在Viewmodel文件夹中创建AssignedCourseData.cs和现有的代码替换为以下代码:
在InstructorController.cs,用下面的代码替换
该代码添加预先加载
接下来,添加用户单击保存时执行的代码。
由于视图没有
如果没有复选框被选中,在
代码遍历所有的课程,在数据库中,然后检查每个课程反对那些当前分配给与之相对的在视图中选择的教练。为方便高效的查找,对后者的两个集合存储在
如果为一门课程的复选框,但本课程并不是在
如果一门课程对应的复选框没有选中,但课程是在
在Views\Instructor\Edit.cshtml,通过添加下面突出显示的代码为
此代码创建一个 HTML 表,其中包含三列。在每一列是其后组成的课程编号和标题的标题的复选框。所有的复选框具有相同的名称 ("selectedCourses"),通知他们将被视为一个组的模型联编程序。每个复选框的
复选框最初呈现时,那些分配给教师的课程有
更改后的课程作业,你会想要能够验证所做的更改,当站点返回到
在Views\Instructor\Index.cshtml,添加课程标题紧接办公室标题,如下面的示例所示:
然后添加新的详细信息单元,紧接着办公室位置详细信息单元:
运行教练索引页后,可以看到分配给每个教师的课程:
指导员看到编辑页上,请单击编辑。
更改某些课程作业并单击保存。你所做的更改反映在索引页上。
注: 编辑教练课程数据而采取的做法工作以及为数有限的课程时。对于要大得多的集合,将需要不同的用户界面和不同的更新方法。
如果您尝试删除教练分配到任何部门作为管理员,您将得到一个参照完整性错误。请参阅本教程中的当前版本将自动从任何部门,其中讲师分配作为管理员移除讲师的额外代码。
下面的插图显示页面,您将利用工作。
为课程自定义创建和编辑页面
当创建新的课程实体时,它必须拥有一个关系到现行的部门。为了推动这项工作,搭建的代码包括控制器方法,并且创建和编辑视图中包括用于选择处的下拉列表。下拉列表中设置Course.DepartmentID的外键属性,,这是所有实体框架所需加载具有适当的
Department实体的
Department导航属性。您可以使用搭建的代码,但改变它微微地添加错误处理和下拉列表进行排序。
在CourseController.cs,删除四个
Edit和
Create方法并替换为以下代码:
public ActionResult Create() { PopulateDepartmentsDropDownList(); return View(); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create( [Bind(Include = "CourseID,Title,Credits,DepartmentID")] Course course) { try { if (ModelState.IsValid) { db.Courses.Add(course); db.SaveChanges(); return RedirectToAction("Index"); } } catch (DataException /* dex */) { //Log the error (uncomment dex variable name after DataException and add a line here to write a log.) ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator."); } PopulateDepartmentsDropDownList(course.DepartmentID); return View(course); } public ActionResult Edit(int id) { Course course = db.Courses.Find(id); PopulateDepartmentsDropDownList(course.DepartmentID); return View(course); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit( [Bind(Include = "CourseID,Title,Credits,DepartmentID")] Course course) { try { if (ModelState.IsValid) { db.Entry(course).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } } catch (DataException /* dex */) { //Log the error (uncomment dex variable name after DataException and add a line here to write a log.) ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator."); } PopulateDepartmentsDropDownList(course.DepartmentID); return View(course); } private void PopulateDepartmentsDropDownList(object selectedDepartment = null) { var departmentsQuery = from d in db.Departments orderby d.Name select d; ViewBag.DepartmentID = new SelectList(departmentsQuery, "DepartmentID", "Name", selectedDepartment); }
PopulateDepartmentsDropDownList方法获取列表按名称排序的所有部门、 创建下拉列表,
SelectList的集合并将集合传递到
ViewBag属性中查看。该方法接受可选的
selectedDepartment参数允许调用代码来指定当呈现下拉列表中将选定的项。视图会将
DepartmentID的名称传递给
DropDownListhelper,和助手就会知道应该命名为
DepartmentID的
SelectList
ViewBag对象中寻找.
HttpGet
Create方法调用
PopulateDepartmentsDropDownList方法无需设置所选的项目,因为有一个新课程部尚未确立:
public ActionResult Create() { PopulateDepartmentsDropDownList(); return View(); }
HttpGet
Edit方法设置所选的项目,基于已分配给课程正在编辑该署的 ID:
public ActionResult Edit(int id) { Course course = db.Courses.Find(id); PopulateDepartmentsDropDownList(course.DepartmentID); return View(course); }
Create和
Edit的
HttpPost方法还包括设置选定的项,当他们出现错误之后重新显示该页的代码:
catch (DataException /* dex */) { //Log the error (uncomment dex variable name after DataException and add a line here to write a log.) ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator."); } PopulateDepartmentsDropDownList(course.DepartmentID); return View(course);
此代码可确保当要显示错误消息,重新显示页上,不管部入选始终保持选定状态。
在Views\Course\Create.cshtml,添加突出显示的代码,以创建一个新的课程编号字段在标题字段之前。正如解释在早些时候的教程中,主键字段不搭建在默认情况下,但此主键是有意义的所以您希望用户能够输入的密钥值。
@model ContosoUniversity.Models.Course @{ ViewBag.Title = "Create"; } <h2>Create</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.ValidationSummary(true) <fieldset> <legend>Course</legend> [code] <div class="editor-label"> @Html.LabelFor(model => model.CourseID) </div> <div class="editor-field"> @Html.EditorFor(model => model.CourseID) @Html.ValidationMessageFor(model => model.CourseID) </div><div class="editor-label">
@Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Credits)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Credits)
@Html.ValidationMessageFor(model => model.Credits)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.DepartmentID, "Department")
</div>
<div class="editor-field">
@Html.DropDownList("DepartmentID", String.Empty)
@Html.ValidationMessageFor(model => model.DepartmentID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}[/code]
在Views\Course\Edit.cshtml、 Views\Course\Delete.cshtml、 Views\Course\Details.cshtml添加课程数字字段在Title字段之前。因为它是主键,它会显示,但不能更改。
<div class="editor-label"> @Html.LabelFor(model => model.CourseID) </div> <div class="editor-field"> @Html.DisplayFor(model => model.CourseID) </div>
运行创建页 (显示路线索引页面,并单击新建) 和输入一门新课程的数据:
单击创建。课程索引页面显示添加到列表中的新课程。在索引页面列表中的部门名称来自于导航属性,显示正确建立了关系。
运行编辑页 (显示路线索引页面,并在课程上单击编辑)。
更改页面上的数据并单击保存。课程索引页显示已更新的课程数据。
添加Instructors编辑页
当您编辑一个教练记录时,你想要能够更新教师的办公室分配。Instructor实体具有一个到零或一个关联
OfficeAssignment实体,这就意味着你必须处理以下情况:
如果用户清除办公室分配,它原本的价值,您必须删除并删除
OfficeAssignment实体。
如果用户输入的办公室分配值,它最初为空,您必须创建一个新的
OfficeAssignment实体。
如果用户更改办公室被分配的值,则必须更改现有的
OfficeAssignment实体中的值。
打开InstructorController.cs ,然后看看
HttpGet
Edit方法:
public ActionResult Edit(int id = 0) { Instructor instructor = db.Instructors.Find(id); if (instructor == null) { return HttpNotFound(); } ViewBag.InstructorID = new SelectList(db.OfficeAssignments, "InstructorID", "Location", instructor.InstructorID); return View(instructor); }
这里搭建的代码不是你想要什么。它设置数据为下拉列表,但你你所需要的是一个文本框。此方法替换为以下代码:
public ActionResult Edit(int id) { Instructor instructor = db.Instructors .Include(i => i.OfficeAssignment) .Where(i => i.InstructorID == id) .Single(); return View(instructor); }
这段代码滴
ViewBag声明,并添加预先加载关联的
OfficeAssignment实体。所以相反的
Where和
Single方法用于选择教练的情况下,不能使用
Find方法,执行预先加载。
用以下代码替换
HttpPost
Edit方法。处理办公室工作分配更新:
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit(int id, FormCollection formCollection) { var instructorToUpdate = db.Instructors .Include(i => i.OfficeAssignment) .Where(i => i.InstructorID == id) .Single(); if (TryUpdateModel(instructorToUpdate, "", new string[] { "LastName", "FirstMidName", "HireDate", "OfficeAssignment" })) { try { if (String.IsNullOrWhiteSpace(instructorToUpdate.OfficeAssignment.Location)) { instructorToUpdate.OfficeAssignment = null; } db.Entry(instructorToUpdate).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } catch (DataException /* dex */) { //Log the error (uncomment dex variable name after DataException and add a line here to write a log. ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator."); } } ViewBag.InstructorID = new SelectList(db.OfficeAssignments, "InstructorID", "Location", id); return View(instructorToUpdate); }
该代码执行以下任务:
获取从数据库使用的当前的
Instructor实体预先加载
OfficeAssignment导航属性。这是你的所作所为中
HttpGet
Edit方法相同。
从模型联编程序的值更新检索到的
Instructor实体。您想要包括的属性使用的TryUpdateModel重载使您到白名单中。这可以防止过度张贴,如所述第二个教程.
if (TryUpdateModel(instructorToUpdate, "", new string[] { "LastName", "FirstMidName", "HireDate", "OfficeAssignment" }))
如果办公室位置为空,将设置
Instructor.OfficeAssignment属性,以便将删除
OfficeAssignment表中的相关的行,则为 null。
if (String.IsNullOrWhiteSpace(instructorToUpdate.OfficeAssignment.Location)) { instructorToUpdate.OfficeAssignment = null; }
将更改保存到数据库中。
在Views\Instructor\Edit.cshtml后
div元素为雇佣日期字段中,, 添加新的字段编辑办公地点:
<div class="editor-label"> @Html.LabelFor(model => model.OfficeAssignment.Location) </div> <div class="editor-field"> @Html.EditorFor(model => model.OfficeAssignment.Location) @Html.ValidationMessageFor(model => model.OfficeAssignment.Location) </div>
运行该页面 (选择教官选项卡,然后点击编辑讲师)。更改办公地点并单击保存.
在指导老师编辑页添加课程作业
教练可以教任何数目的课程。现在您将通过添加更改课程作业使用一组复选框,如下面的屏幕快照中所示的能力增强导师编辑页面:Course和
Instructor实体之间的关系是多,这意味着您没有直接访问到联接表。相反,您将添加和删除实体,从
Instructor.Courses导航属性。
用户界面中,使您能够更改哪些课程的讲师是分配给是一组复选框。显示数据库中的每一门课程的复选框,并选择了那些讲师当前分配给。用户可以选择或清除复选框以更改课程作业。如果课程数目大得多,你可能想要使用不同的方法,在视图中,显示数据,但您将使用相同的方法操纵导航属性以创建或删除关系。
为列表中的复选框提供数据到视图,您将使用一个视图模型类。在Viewmodel文件夹中创建AssignedCourseData.cs和现有的代码替换为以下代码:
namespace ContosoUniversity.ViewModels { public class AssignedCourseData { public int CourseID { get; set; } public string Title { get; set; } public bool Assigned { get; set; } } }
在InstructorController.cs,用下面的代码替换
HttpGet
Edit方法。高亮行为所做的更改。
public ActionResult Edit(int id) { Instructor instructor = db.Instructors .Include(i => i.OfficeAssignment) .Include(i => i.Courses) .Where(i => i.InstructorID == id) .Single(); PopulateAssignedCourseData(instructor); 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 = course.CourseID, Title = course.Title, Assigned = instructorCourses.Contains(course.CourseID) }); } ViewBag.Courses= viewModel; }
该代码添加预先加载
Courses导航属性,调用新的
PopulateAssignedCourseData方法,以便为使用
AssignedCourseData视图模型类的复选框数组提供的信息。
PopulateAssignedCourseData方法中的代码读取通过所有
Course实体以加载列表,使用视图模型类的课程。对于每个课程,该代码检查教师的
Courses导航属性中是否存在该课程。若要创建高效的查找,检查是否课程指派给指导员时,分配给教师的课程都放入HashSet集合。
Assigned属性设置为
true,课程教师分配。查看将使用此属性来确定哪些复选框必须显示为选中。最后,列表被传递给一个
ViewBag属性中的视图。
接下来,添加用户单击保存时执行的代码。
HttpPost
Edit方法替换以下代码中,调用更新
Instructor实体的
Courses导航属性的新方法。突出显示所做的更改。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id, FormCollection formCollection, string[] selectedCourses)
{
var instructorToUpdate = db.Instructors
.Include(i => i.OfficeAssignment)
.Include(i => i.Courses)
.Where(i => i.InstructorID == id)
.Single();
if (TryUpdateModel(instructorToUpdate, "",
new string[] { "LastName", "FirstMidName", "HireDate", "OfficeAssignment" }))
{
try
{
if (String.IsNullOrWhiteSpace(instructorToUpdate.OfficeAssignment.Location)) { instructorToUpdate.OfficeAssignment = null; }
UpdateInstructorCourses(selectedCourses, instructorToUpdate);
db.Entry(instructorToUpdate).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
catch (DataException /* dex */)
{
//Log the error (uncomment dex variable name after DataException and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
}
PopulateAssignedCourseData(instructorToUpdate);
return View(instructorToUpdate);
}
private void UpdateInstructorCourses(string[] selectedCourses, Instructor instructorToUpdate)
{
if (selectedCourses== null)
{
instructorToUpdate.Courses= new List<Course>();
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(course); } }
else { if (instructorCourses.Contains(course.CourseID)) { instructorToUpdate.Courses.Remove(course); } }
}
}
由于视图没有
Course实体的集合,模型联编程序不能自动更新
Courses导航属性。而不是使用模型联编程序更新课程导航属性,你可以做到在新的
UpdateInstructorCourses方法。因此,您需要将
Courses属性排除模型绑定。这并不需要对调用TryUpdateModel ,因为您正在使用白名单过载和
Courses不在包含列表中的代码的任何更改。
如果没有复选框被选中,在
UpdateInstructorCourses代码初始化具有一个空集合的
Courses导航属性:
if (selectedCourses== null)
{
instructorToUpdate.Courses= new List<Course>();
return;
}
代码遍历所有的课程,在数据库中,然后检查每个课程反对那些当前分配给与之相对的在视图中选择的教练。为方便高效的查找,对后者的两个集合存储在
HashSet对象。
如果为一门课程的复选框,但本课程并不是在
Instructor.Courses导航属性,该课程添加到中的导航属性的集合。
if (selectedCoursesHS.Contains(course.CourseID.ToString())) { if (!instructorCourses.Contains(course.CourseID)) { instructorToUpdate.Courses.Add(course); } }
如果一门课程对应的复选框没有选中,但课程是在
Instructor.Courses导航属性,课程是从导航属性中删除。
else { if (instructorCourses.Contains(course.CourseID)) { instructorToUpdate.Courses.Remove(course); } }
在Views\Instructor\Edit.cshtml,通过添加下面突出显示的代码为
OfficeAssignment字段
div元素后立即添加课程领域与数组的复选框:
@model ContosoUniversity.Models.Instructor
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Instructor</legend>
@Html.HiddenFor(model => model.InstructorID)
<div class="editor-label">
@Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.LastName)
@Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.FirstMidName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.FirstMidName)
@Html.ValidationMessageFor(model => model.FirstMidName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.HireDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.HireDate)
@Html.ValidationMessageFor(model => model.HireDate)
</div>
<div class="editor-label"> @Html.LabelFor(model => model.OfficeAssignment.Location) </div> <div class="editor-field"> @Html.EditorFor(model => model.OfficeAssignment.Location) @Html.ValidationMessageFor(model => model.OfficeAssignment.Location) </div>
<div class="editor-field">
<table>
<tr>
@{
int cnt = 0;
List<ContosoUniversity.ViewModels.AssignedCourseData> courses = ViewBag.Courses;
foreach (var course in courses) {
if (cnt++ % 3 == 0) {
@: </tr> <tr>
}
@: <td>
<input type="checkbox"
name="selectedCourses"
value="@course.CourseID"
@(Html.Raw(course.Assigned ? "checked=\"checked\"" : "")) />
@course.CourseID @: @course.Title
@:</td>
}
@: </tr>
}
</table>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
此代码创建一个 HTML 表,其中包含三列。在每一列是其后组成的课程编号和标题的标题的复选框。所有的复选框具有相同的名称 ("selectedCourses"),通知他们将被视为一个组的模型联编程序。每个复选框的
value属性设置为的值
CourseID.当该页时,模型联编程序将数组传递给控制器
CourseID值只选定复选框组成。
复选框最初呈现时,那些分配给教师的课程有
checked属性,选择它们 (显示他们检查)。
更改后的课程作业,你会想要能够验证所做的更改,当站点返回到
Index页面。因此,您需要将列添加到该页面中的表。在这种情况下你不需要使用
ViewBag对象,因为你想要显示的信息已经被你正在传递到页中的模型作为
Instructor实体的
Courses导航属性。
在Views\Instructor\Index.cshtml,添加课程标题紧接办公室标题,如下面的示例所示:
<tr> <th></th> <th>Last Name</th> <th>First Name</th> <th>Hire Date</th> <th>Office</th> <th>Courses</th> </tr>
然后添加新的详细信息单元,紧接着办公室位置详细信息单元:
@model ContosoUniversity.ViewModels.InstructorIndexData
@{
ViewBag.Title = "Instructors";
}
<h2>Instructors</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr> <th></th> <th>Last Name</th> <th>First Name</th> <th>Hire Date</th> <th>Office</th> <th>Courses</th> </tr>
@foreach (var item in Model.Instructors)
{
string selectedRow = "";
if (item.InstructorID == ViewBag.InstructorID)
{
selectedRow = "selectedrow";
}
<tr class="@selectedRow" valign="top">
<td>
@Html.ActionLink("Select", "Index", new { id = item.InstructorID }) |
@Html.ActionLink("Edit", "Edit", new { id = item.InstructorID }) |
@Html.ActionLink("Details", "Details", new { id = item.InstructorID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.InstructorID })
</td>
<td>
@item.LastName
</td>
<td>
@item.FirstMidName
</td>
<td>
@String.Format("{0:d}", item.HireDate)
</td>
<td>
@if (item.OfficeAssignment != null)
{
@item.OfficeAssignment.Location
}
</td>
<td>
@{
foreach (var course in item.Courses)
{
@course.CourseID @: @course.Title <br />
}
}
</td>
</tr>
}
</table>
@if (Model.Courses!= null)
{
<h3>CoursesTaught by Selected Instructor</h3>
<table>
<tr>
<th></th>
<th>ID</th>
<th>Title</th>
<th>Department</th>
</tr>
@foreach (var item in Model.Courses)
{
string selectedRow = "";
if (item.CourseID == ViewBag.CourseID)
{
selectedRow = "selectedrow";
}
<tr class="@selectedRow">
<td>
@Html.ActionLink("Select", "Index", new { courseID = item.CourseID })
</td>
<td>
@item.CourseID
</td>
<td>
@item.Title
</td>
<td>
@item.Department.Name
</td>
</tr>
}
</table>
}
@if (Model.Enrollments != null)
{
<h3>Students Enrolled in Selected Course</h3>
<table>
<tr>
<th>Name</th>
<th>Grade</th>
</tr>
@foreach (var item in Model.Enrollments)
{
<tr>
<td>
@item.Student.FullName
</td>
<td>
@Html.DisplayFor(modelItem => item.Grade)
</td>
</tr>
}
</table>
}
</td>
运行教练索引页后,可以看到分配给每个教师的课程:
指导员看到编辑页上,请单击编辑。
更改某些课程作业并单击保存。你所做的更改反映在索引页上。
注: 编辑教练课程数据而采取的做法工作以及为数有限的课程时。对于要大得多的集合,将需要不同的用户界面和不同的更新方法。
更新删除方法
改变 HttpPost 删除方法中的代码,所以教练被删除时删除办公室分配记录 (如果有):[HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(int id) { Instructor instructor = db.Instructors .Include(i => i.OfficeAssignment) .Where(i => i.InstructorID == id) .Single(); instructor.OfficeAssignment = null; db.Instructors.Remove(instructor); db.SaveChanges(); return RedirectToAction("Index"); }
如果您尝试删除教练分配到任何部门作为管理员,您将得到一个参照完整性错误。请参阅本教程中的当前版本将自动从任何部门,其中讲师分配作为管理员移除讲师的额外代码。
摘要
现在,您已完成此简介工作的相关数据。到目前为止这些教程中你做过全范围的 CRUD 操作,但是你没有先处理并发问题。下一个教程将并发的话题引入、 解释选项来处理它,并添加到你已经写出了一种实体类型的 CRUD 代码处理的并发。相关文章推荐
- EntityFramework_MVC4中EF5 新手入门教程之五 ---5.通过 Entity Framework 读取相关数据
- EntityFramework_MVC4中EF5 新手入门教程之七 ---7.通过 Entity Framework 处理并发
- EntityFramework_MVC4中EF5 新手入门教程之三 ---3.排序、 筛选和分页
- EntityFramework_MVC4中EF5 新手入门教程之二 ---2.执行基本的 CRUD 功能
- ASP.NET MVC4 新手入门教程特别篇之一----Code First Migrations更新数据库结构(数据迁移)修改Entity FrameWork 数据结构(不删除数据)
- 【EntityFramework系列教程六,翻译】在ASP.NET MVC程序中使用EntityFramework对相关数据进行更新
- Provisioning Services 7.8 入门系列教程之十 通过类自动更新虚拟磁盘
- Scott Mitchell 的ASP.NET 2.0数据教程之十七:: 研究插入、更新和删除的关联事件
- 【原创】新手用外挂来学C语言,外挂入门教程【2013.03.12更新V5.1版
- highcharts图表组件入门教程:如何监听柱状图柱子点击事件动态更新当前数据点数值和所对应X轴刻度
- Android基础入门教程——2.4.6 ListView的数据更新问题
- Scott Mitchell 的ASP.NET 2.0数据教程之十七:: 研究插入、更新和删除的关联事件
- Scott Mitchell 的ASP.NET 2.0数据教程之十七:: 研究插入、更新和删除的关联事件
- ASP.NET MVC4 新手入门教程之五 ---5.用控制器访问模型数据
- Scott Mitchell 的ASP.NET 2.0数据教程之十七:: 研究插入、更新和删除的关联事件
- Provisioning Services 7.8 入门系列教程之十一 通过版本控制自动更新虚拟磁盘
- ECharts图表组件入门教程:如何动态读取数组内的数据至echarts图表且动态更新图表Y轴刻度单位
- Scott Mitchell 的ASP.NET 2.0数据教程之十七:: 研究插入、更新和删除的关联事件
- MVC4+EF新手入门:编辑数据+删除数据
- EntityFramework 5.0 CodeFirst 教程04-查询,插入,更新,和删除数据