Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
tarafından Tom Dykstra
Contoso University örnek web uygulaması, Entity Framework 5 Code First ve Visual Studio 2012 kullanarak ASP.NET MVC 4 uygulamalarının nasıl oluşturulacağını gösterir. Öğretici serisi hakkında bilgi için serideki ilk öğreticiye bakın.
Not
Çözemediğiniz bir sorunla karşılaşırsanız tamamlanmış bölümü indirin ve sorununuzu yeniden oluşturmayı deneyin. Kodunuzu tamamlanmış kodla karşılaştırarak sorunun çözümünü genel olarak bulabilirsiniz. Bazı yaygın hatalar ve bunların nasıl çözüldüğü için bkz . Hatalar ve Geçici Çözümler.
Önceki öğreticide ilgili verileri görüntülemişsiniz; bu öğreticide ilgili verileri güncelleştireceksiniz. Çoğu ilişki için bu, uygun yabancı anahtar alanları güncelleştirilerek yapılabilir. Çoka çok ilişkiler için Entity Framework birleştirme tablosunu doğrudan kullanıma sunmaz, bu nedenle uygun gezinti özelliklerine ve bu özelliklere açıkça varlık ekleyip kaldırmanız gerekir.
Aşağıdaki çizimlerde birlikte çalışacağınız sayfalar gösterilmektedir.


Kurslar için Sayfa Oluştur ve Düzenle'yi özelleştirme
Yeni bir kurs varlığı oluşturulduğunda, var olan bir bölümle ilişkisi olmalıdır. Bunu kolaylaştırmak için, yapı iskelesi oluşturulmuş kod denetleyici yöntemlerini ve bölümü seçmek için açılan liste içeren Oluşturma ve Düzenleme görünümlerini içerir. Açılan liste yabancı anahtar özelliğini ayarlar Course.DepartmentID ve gezinti özelliğini uygun Department varlığa yüklemek Department için Entity Framework'ün tüm ihtiyacı bu kadardır. İskeleli kodu kullanacaksınız, ancak hata işleme eklemek ve açılan listeyi sıralamak için biraz değiştireceksiniz.
CourseController.cs dört Edit ve Create yöntemini silin ve bunları aşağıdaki kodla değiştirin:
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 yöntemi, ada göre sıralanmış tüm bölümlerin listesini alır, açılan liste için bir SelectList koleksiyon oluşturur ve koleksiyonu bir ViewBag özellikteki görünüme geçirir. yöntemi, arama kodunun açılan liste işlenirken seçilecek öğeyi belirtmesine izin veren isteğe bağlı selectedDepartment parametreyi kabul eder. Görünüm, adı DepartmentID yardımcıya DropDownList geçirir ve yardımcı daha sonra adlı DepartmentIDbir SelectList nesneye ViewBag bakacağını bilir.
HttpGet Create Yöntemi, seçilen öğeyi ayarlamadan yöntemini çağırırPopulateDepartmentsDropDownList, çünkü yeni bir kurs için bölüm henüz oluşturulmadı:
public ActionResult Create()
{
PopulateDepartmentsDropDownList();
return View();
}
HttpGet Edit yöntemi, düzenlenen kursa zaten atanmış olan bölümün kimliğine göre seçili öğeyi ayarlar:
public ActionResult Edit(int id)
{
Course course = db.Courses.Find(id);
PopulateDepartmentsDropDownList(course.DepartmentID);
return View(course);
}
Hem HttpPost hem de Create Edit için yöntemler, bir hatadan sonra sayfayı yeniden dağıttığında seçili öğeyi ayarlayan kodu içerir:
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);
Bu kod, sayfa yeniden görüntülendiğinde hata iletisini gösterecek şekilde görüntülendiğinde, seçilen departmanların seçili kalmasını sağlar.
Views\Course\Create.cshtml'de, Başlık alanından önce yeni bir kurs numarası alanı oluşturmak için vurgulanan kodu ekleyin. Önceki bir öğreticide açıklandığı gibi, birincil anahtar alanları varsayılan olarak iskele oluşturmaz, ancak bu birincil anahtar anlamlıdır, bu nedenle kullanıcının anahtar değerini girebilmesini istersiniz.
@model ContosoUniversity.Models.Course
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Course</legend>
<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")
}
Views\Course\Edit.cshtml, Views\Course\Delete.cshtml ve Views\Course\Details.cshtml'de, Başlık alanından önce bir kurs numarası alanı ekleyin. Birincil anahtar olduğundan görüntülenir, ancak değiştirilemez.
<div class="editor-label">
@Html.LabelFor(model => model.CourseID)
</div>
<div class="editor-field">
@Html.DisplayFor(model => model.CourseID)
</div>
Oluştur sayfasını çalıştırın (Kurs Dizini sayfasını görüntüleyin ve Yeni Oluştur'a tıklayın) ve yeni bir kursun verilerini girin:

Oluştur’a tıklayın. Kurs Dizini sayfası, listeye eklenen yeni kursla birlikte görüntülenir. Dizin sayfası listesindeki bölüm adı, ilişkinin doğru kurulduğunu gösteren gezinti özelliğinden gelir.

Düzenle sayfasını çalıştırın (Kurs Dizini sayfasını görüntüleyin ve bir kursta Düzenle'ye tıklayın).

Sayfadaki verileri değiştirin ve Kaydet'e tıklayın. Kurs Dizini sayfası, güncelleştirilmiş kurs verileriyle birlikte görüntülenir.
Eğitmenler için Düzenleme Sayfası Ekleme
Eğitmen kaydını düzenlerken, eğitmenin ofis ödevini güncelleştirebilmek istersiniz. Varlığın Instructor varlıkla OfficeAssignment bire sıfır veya bir ilişkisi vardır; bu da aşağıdaki durumları işlemeniz gerektiği anlamına gelir:
- Kullanıcı office atamasını temizlerse ve başlangıçta bir değeri varsa varlığı kaldırmanız ve silmeniz
OfficeAssignmentgerekir. - Kullanıcı bir office atama değeri girerse ve başlangıçta boşsa, yeni
OfficeAssignmentbir varlık oluşturmanız gerekir. - Kullanıcı bir office atamasının değerini değiştirirse, var olan
OfficeAssignmentbir varlıktaki değeri değiştirmeniz gerekir.
InstructorController.cs açın ve yöntemine HttpGet Edit bakın:
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);
}
Buradaki yapı iskelesi oluşturulmuş kod istediğiniz gibi değil. Açılan liste için veri ayarlanıyor, ancak ihtiyacınız olan şey bir metin kutusu. Bu yöntemi aşağıdaki kodla değiştirin:
public ActionResult Edit(int id)
{
Instructor instructor = db.Instructors
.Include(i => i.OfficeAssignment)
.Where(i => i.InstructorID == id)
.Single();
return View(instructor);
}
Bu kod deyimini ViewBag bırakır ve ilişkili OfficeAssignment varlık için istekli yükleme ekler. yöntemiyle hevesle Find yükleme gerçekleştiremezsiniz, bu nedenle Where eğitmeni seçmek için bunun yerine ve Single yöntemleri kullanılır.
HttpPost Edit yöntemini aşağıdaki kodla değiştirin. Office atama güncelleştirmelerini işleyen:
[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);
}
Kod aşağıdakileri yapar:
Gezinti özelliği için istekli yükleme kullanarak veritabanından
OfficeAssignmentgeçerliInstructorvarlığı alır. Bu, yönteminde yaptığınız işlemleHttpGetEditaynıdır.Alınan
Instructorvarlığı model bağlayıcısından alınan değerlerle güncelleştirir. Kullanılan TryUpdateModel aşırı yüklemesi, eklemek istediğiniz özellikleri güvenli bir şekilde listelemenizi sağlar. Bu, ikinci öğreticide açıklandığı gibi fazla göndermeyi önler.if (TryUpdateModel(instructorToUpdate, "", new string[] { "LastName", "FirstMidName", "HireDate", "OfficeAssignment" }))Ofis konumu boşsa, tablodaki ilgili satırın
Instructor.OfficeAssignmentOfficeAssignmentsilinmesi için özelliği null olarak ayarlar.if (String.IsNullOrWhiteSpace(instructorToUpdate.OfficeAssignment.Location)) { instructorToUpdate.OfficeAssignment = null; }Değişiklikleri veritabanına kaydeder.
Views\Instructor\Edit.cshtml içinde, İşe Alma Tarihi alanına ilişkin öğelerden sonradiv, ofis konumunu düzenlemek için yeni bir alan ekleyin:
<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>
Sayfayı çalıştırın (Eğitmenler sekmesini seçin ve ardından bir eğitmende Düzenle'ye tıklayın). Office Konumunu değiştirin ve Kaydet'e tıklayın.

Eğitmen Düzenleme Sayfasına Kurs Ödevleri Ekleme
Eğitmenler herhangi bir sayıda ders verebilir. Şimdi, aşağıdaki ekran görüntüsünde gösterildiği gibi, bir onay kutusu grubu kullanarak kurs ödevlerini değiştirme özelliğini ekleyerek Eğitmen Düzenleme sayfasını geliştireceksiniz:

ve Instructor varlıkları arasındaki Course ilişki çoka çok şeklindedir ve bu da birleştirme tablosuna doğrudan erişiminiz olmadığı anlamına gelir. Bunun yerine, gezinti özelliğine ve gezinti özelliğinden Instructor.Courses varlık ekleyip kaldıracaksınız.
Eğitmenin hangi kurslara atandığını değiştirmenize olanak tanıyan kullanıcı arabirimi bir onay kutusu grubudur. Veritabanındaki her kurs için bir onay kutusu görüntülenir ve eğitmenin şu anda atanmış olduğu kurslar seçilir. Kullanıcı, kurs ödevlerini değiştirmek için onay kutularını seçebilir veya temizleyebilir. Kurs sayısı çok daha fazlaysa, büyük olasılıkla verileri görünümde sunmak için farklı bir yöntem kullanmak istersiniz, ancak ilişkileri oluşturmak veya silmek için gezinti özelliklerini işlemek için aynı yöntemi kullanırsınız.
Onay kutuları listesinin görünümüne veri sağlamak için bir görünüm modeli sınıfı kullanacaksınız. ViewModels klasöründe AssignedCourseData.cs oluşturun ve mevcut kodu aşağıdaki kodla değiştirin:
namespace ContosoUniversity.ViewModels
{
public class AssignedCourseData
{
public int CourseID { get; set; }
public string Title { get; set; }
public bool Assigned { get; set; }
}
}
InstructorController.cs'da yöntemini aşağıdaki kodla değiştirin HttpGet Edit. Değişiklikler vurgulanır.
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;
}
Kod, gezinti özelliği için Courses hevesle yüklemeyi ekler ve görünüm modeli sınıfını kullanarak AssignedCourseData onay kutusu dizisi için bilgi sağlamak üzere yeni PopulateAssignedCourseData yöntemi çağırır.
Yöntemindeki PopulateAssignedCourseData kod, görünüm modeli sınıfını kullanarak bir kurs listesi yüklemek için tüm Course varlıklarda okur. Her kurs için kod, kursun eğitmenin Courses gezinti özelliğinde mevcut olup olmadığını denetler. Eğitmene bir kursun atanıp atanmadığını denetlerken verimli arama oluşturmak için, eğitmene atanan kurslar bir HashSet koleksiyonuna konur. Assigned Özellik, eğitmenin atandığı kurslar için olarak ayarlanırtrue. Görünüm, hangi onay kutularının seçili olarak görüntülenmesi gerektiğini belirlemek için bu özelliği kullanır. Son olarak, liste bir ViewBag özellikteki görünüme geçirilir.
Ardından, kullanıcı Kaydet'e tıkladığında yürütülen kodu ekleyin. HttpPost Edit yöntemini, varlığın gezinti özelliğini Instructor güncelleştiren Courses yeni bir yöntemi çağıran aşağıdaki kodla değiştirin. Değişiklikler vurgulanır.
[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);
}
}
}
}
Görünümde varlık koleksiyonu Course olmadığından model bağlayıcısı gezinti özelliğini otomatik olarak güncelleştiremez Courses . Kurslar gezinti özelliğini güncelleştirmek için model bağlayıcısını kullanmak yerine, bunu yeni UpdateInstructorCourses yöntemde yapacaksınız. Bu nedenle, özelliğini model bağlamasının Courses dışında tutmanız gerekir. Güvenli liste aşırı yüklemesini kullandığınızdan ve Courses ekleme listesinde olmadığından, bu işlem TryUpdateModel'i çağıran kodda herhangi bir değişiklik gerektirmez.
Onay kutusu seçilmediyse içindeki kod UpdateInstructorCourses , gezinti özelliğini boş bir koleksiyonla başlatır Courses :
if (selectedCourses == null)
{
instructorToUpdate.Courses = new List<Course>();
return;
}
Kod daha sonra veritabanındaki tüm kurslar arasında döngü oluşturur ve her kursu şu anda eğitmene atanmış olanlarla görünümde seçilenler arasında denetler. Verimli aramaları kolaylaştırmak için, ikinci iki koleksiyon nesnelerde HashSet depolanır.
Kursun onay kutusu seçiliyse ancak kurs gezinti özelliğinde Instructor.Courses değilse, kurs gezinti özelliğindeki koleksiyona eklenir.
if (selectedCoursesHS.Contains(course.CourseID.ToString()))
{
if (!instructorCourses.Contains(course.CourseID))
{
instructorToUpdate.Courses.Add(course);
}
}
Kursun onay kutusu seçili değilse ancak kurs gezinti özelliğindeyse Instructor.Courses , kurs gezinti özelliğinden kaldırılır.
else
{
if (instructorCourses.Contains(course.CourseID))
{
instructorToUpdate.Courses.Remove(course);
}
}
Views\Instructor\Edit.cshtml içinde, alan öğelerinin OfficeAssignment hemen arkasına div aşağıdaki vurgulanmış kodu ekleyerek onay kutuları dizisi içeren bir Kurslar alanı ekleyin:
@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")
}
Bu kod, üç sütunu olan bir HTML tablosu oluşturur. Her sütunda bir onay kutusu ve ardından kurs numarası ve başlığından oluşan bir resim yazısı bulunur. Onay kutularının tümü aynı ada ("selectedCourses") sahiptir ve bu da model bağlayıcısına grup olarak ele alınacaklarını bildirir. value Her onay kutusunun özniteliği Sayfa deftere nakledildiğinde değeri CourseID. olarak ayarlanır, model bağlayıcısı denetleyiciye yalnızca seçili onay kutuları için değerlerden oluşan CourseID bir dizi geçirir.
Onay kutuları başlangıçta işlendiğinde, eğitmene atanan kurslar için olan özniteliklere sahip checked olur ve bu öznitelikler bunları seçer (işaretli olarak görüntülenir).
Kurs ödevlerini değiştirdikten sonra, site sayfaya döndüğünde Index değişiklikleri doğrulayabilmeniz gerekir. Bu nedenle, bu sayfadaki tabloya bir sütun eklemeniz gerekir. Görüntülemek istediğiniz bilgiler, model olarak sayfaya geçirdiğiniz varlığın gezinti özelliğinde Courses Instructor olduğundan bu durumda nesnesini kullanmanız ViewBag gerekmez.
Views\Instructor\Index.cshtml içinde, aşağıdaki örnekte gösterildiği gibi Office başlığının hemen ardından bir Kurslar başlığı ekleyin:
<tr>
<th></th>
<th>Last Name</th>
<th>First Name</th>
<th>Hire Date</th>
<th>Office</th>
<th>Courses</th>
</tr>
Ardından, ofis konumu ayrıntı hücresinin hemen ardından yeni bir ayrıntı hücresi ekleyin:
@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>Courses Taught 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>
}
Her eğitmene atanan dersleri görmek için Eğitmen Dizini sayfasını çalıştırın:

Düzenle sayfasını görmek için eğitmende Düzenle'ye tıklayın.

Bazı kurs ödevlerini değiştirin ve Kaydet'e tıklayın. Yaptığınız değişiklikler Dizin sayfasına yansıtılır.
Not: Eğitmen kurs verilerini düzenleme yaklaşımı, sınırlı sayıda kurs olduğunda iyi sonuç verir. Çok daha büyük koleksiyonlar için farklı bir kullanıcı arabirimi ve farklı bir güncelleştirme yöntemi gerekir.
Delete Yöntemini Güncelleştirme
Eğitmen silindiğinde office atama kaydının (varsa) silinmesi için HttpPost Delete yöntemindeki kodu değiştirin:
[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");
}
Bir bölüme yönetici olarak atanan bir eğitmeni silmeye çalışırsanız bilgi tutarlılığı hatası alırsınız. Eğitmenin yönetici olarak atandığı herhangi bir departmandan eğitmeni otomatik olarak kaldıracak ek kod için bu öğreticinin geçerli sürümüne bakın.
Özet
İlgili verilerle çalışmaya yönelik bu giriş adımını tamamladınız. Şu ana kadar bu öğreticilerde çok çeşitli CRUD işlemleri yaptınız, ancak eşzamanlılık sorunlarıyla ilgilenmediniz. Sonraki öğreticide eşzamanlılık konusu tanıtılacak, işleme seçeneklerini açıklayacak ve zaten bir varlık türü için yazdığınız CRUD koduna eşzamanlılık işlemesi eklenecektir.
Diğer Entity Framework kaynaklarına bağlantılar, bu serinin son öğreticisinin sonunda bulunabilir.