bir ASP.NET MVC Uygulamasında Entity Framework ile İlgili Verileri Güncelleştirme (6/10)
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. Genellikle kodunuzu tamamlanmış kodla karşılaştırarak sorunun çözümünü 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, uygun yabancı anahtar alanları güncelleştirilerek bu yapılabilir. Çoka çok ilişkiler için, Entity Framework birleştirme tablosunu doğrudan kullanıma sunmaz, bu nedenle uygun gezinti özelliklerine açıkça varlık ekleyip kaldırmanız gerekir.
Aşağıdaki çizimlerde, çalışacağınız sayfalar gösterilmektedir.
Kurslar için Sayfa Oluşturma ve DüzenlemeYi Özelleştirme
Yeni bir kurs varlığı oluşturulduğunda, var olan bir departmanla 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 ihtiyacı olan tek şey bu olur. yapı iskelesi oluşturulmuş kodu kullanacaksınız, ancak hata işleme eklemek ve açılan listeyi sıralamak için biraz değiştireceksiniz.
CourseController.cs dosyasında, 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, çağıran kodun açılan liste işlenirken seçilecek öğeyi belirtmesine izin veren isteğe bağlı selectedDepartment
parametresini kabul eder. Görünüm, adı DepartmentID
yardımcıya DropDownList
geçirir ve ardından yardımcı, adlı DepartmentID
bir SelectList
için nesneye bakmayı ViewBag
bilir.
Yöntem HttpGet
Create
, seçilen öğeyi ayarlamadan yöntemini çağırır PopulateDepartmentsDropDownList
, çü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);
}
HttpPost
hem 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, hangi departman seçildiyse seçili kalmasını sağlar.
Views\Course\Create.cshtml içinde, 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ının önüne 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 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ırıp silmeniz
OfficeAssignment
gerekir. - Kullanıcı bir office atama değeri girerse ve başlangıçta boşsa, yeni
OfficeAssignment
bir varlık oluşturmanız gerekir. - Kullanıcı office atamasının değerini değiştirirse, var olan
OfficeAssignment
bir varlıktaki değeri değiştirmeniz gerekir.
InstructorController.cs dosyasını 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);
}
Burada iskelesi oluşturulmuş kod istediğiniz gibi değildir. Açılan liste için veri ayarlanıyor, ancak size gereken bir metin kutusudur. 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 hızlı 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
OfficeAssignment
geçerliInstructor
varlığı alır. Bu, yöntemindeHttpGet
Edit
yaptığınızla aynıdır.Alınan
Instructor
varlığı model bağlayıcısından alınan değerlerle Güncelleştirmeler. 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.OfficeAssignment
OfficeAssignment
silinmesi 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ının öğelerinden 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 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 atandığı dersleri 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 o anda atandığı 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 isteyebilirsiniz, ancak ilişkileri oluşturmak veya silmek için gezinti özelliklerini işlemek için de 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 dosyasını 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 dosyasında yöntemini aşağıdaki kodla değiştirinHttpGet
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
hızlı yükleme 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ıkları okur. Kod, her kurs için kursun eğitmenin Courses
gezinti özelliğinde 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ız ve Courses
ekleme listesinde yer almadığınız için TryUpdateModel'içağıran kodda herhangi bir değişiklik yapılması gerekmez.
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 eğitmene atanmış olanlarla görünümde seçilenler arasında karşılaştırarak 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, kurs numarası ve başlığından oluşan bir başlık izleyen bir onay kutusu bulunur. Onay kutularının tümü aynı ada sahiptir ("selectedCourses"), model bağlayıcısına grup olarak kabul edileceklerini bildirir. value
Her onay kutusunun özniteliği Sayfa deftere nakledildiğinde değerine CourseID.
ayarlanır, model bağlayıcısı denetleyiciye yalnızca seçili onay kutularının değerlerinden oluşan CourseID
bir dizi geçirir.
Onay kutuları başlangıçta işlendiğinde, eğitmene atanan kurslara yönelik olanlar özniteliklere sahiptir checked
ve bu öznitelikler bunları seçer (işaretli olarak görüntülenir).
Kurs ödevlerini değiştirdikten sonra, site sayfaya döndüğünde değişiklikleri doğrulayabilmeniz gerekir Index
. Bu nedenle, bu sayfadaki tabloya bir sütun eklemeniz gerekir. Bu durumda, görüntülemek istediğiniz bilgiler zaten model olarak sayfaya geçirdiğiniz varlığın gezinti özelliğinde Courses
Instructor
olduğundan 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 kursları 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 ders verilerini düzenlemek için uygulanan 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 tanıtımı tamamladınız. Bu öğreticilerde şimdiye kadar birçok CRUD işlemi gerçekleştirdiniz ancak eşzamanlılık sorunlarıyla ilgilenmediniz. Sonraki öğreticide eşzamanlılık konusu tanıtılacak, işleme seçeneklerini açıklanacak ve bir varlık türü için daha önce yazdığınız CRUD koduna eşzamanlılık işleme eklenecektir.
Diğer Entity Framework kaynaklarına bağlantılar , bu serideki son öğreticinin sonunda bulunabilir.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin