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.
Önceki öğreticide ilgili verileri görüntülemişsiniz. Bu öğreticide ilgili verileri güncelleştireceksiniz. Çoğu ilişkide, bu işlem yabancı anahtar alanları veya gezinti özellikleri 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 varlık ekleyip kaldırırsınız.
Aşağıdaki çizimlerde, çalışacağınız bazı sayfalar gösterilmektedir.



Bu öğreticide şunları yaptınız:
- Kurs sayfalarını özelleştirme
- Eğitmenlere office ekleme sayfası
- Eğitmenler sayfasına kurs ekleme
- DeleteConfirmed Güncelleştirme
- Oluştur sayfasına ofis konumu ve kursları ekleme
Önkoşullar
Kurs sayfalarını ö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 Create ve Edit 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 (RetryLimitExceededException /* dex */)
{
//Log the error (uncomment dex variable name 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)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Course course = db.Courses.Find(id);
if (course == null)
{
return HttpNotFound();
}
PopulateDepartmentsDropDownList(course.DepartmentID);
return View(course);
}
[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public ActionResult EditPost(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var courseToUpdate = db.Courses.Find(id);
if (TryUpdateModel(courseToUpdate, "",
new string[] { "Title", "Credits", "DepartmentID" }))
{
try
{
db.SaveChanges();
return RedirectToAction("Index");
}
catch (RetryLimitExceededException /* dex */)
{
//Log the error (uncomment dex variable name 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(courseToUpdate.DepartmentID);
return View(courseToUpdate);
}
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);
}
Dosyanın başına aşağıdaki using deyimi ekleyin:
using System.Data.Entity.Infrastructure;
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 DropDownList yardımcısına 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)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Course course = db.Courses.Find(id);
if (course == null)
{
return HttpNotFound();
}
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 (RetryLimitExceededException /* dex */)
{
//Log the error (uncomment dex variable name 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.
Kurs görünümleri, bölüm alanı için açılan listelerle zaten iskelelenmiştir, ancak bu alan için DepartmentID resim yazısını istemezsiniz; bu nedenle, resim yazısını değiştirmek için Views\Course\Create.cshtml dosyasında aşağıdaki vurgulanmış değişikliği yapın.
@model ContosoUniversity.Models.Course
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Course</h4>
<hr />
@Html.ValidationSummary(true)
<div class="form-group">
@Html.LabelFor(model => model.CourseID, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CourseID)
@Html.ValidationMessageFor(model => model.CourseID)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Credits, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Credits)
@Html.ValidationMessageFor(model => model.Credits)
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2" for="DepartmentID">Department</label>
<div class="col-md-10">
@Html.DropDownList("DepartmentID", String.Empty)
@Html.ValidationMessageFor(model => model.DepartmentID)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Views\Course\Edit.cshtml içinde aynı değişikliği yapın.
Normalde, anahtar değeri veritabanı tarafından oluşturulduğundan ve değiştirilebildiğinden ve kullanıcılara görüntülenecek anlamlı bir değer olmadığından, iskele birincil anahtarın iskelesini oluşturmaz. Kurs varlıkları için yapı iskelesi, özniteliğin CourseID kullanıcının birincil anahtar değerini girebileceği anlamına geldiğini anladığı DatabaseGeneratedOption.None için alan için bir metin kutusu içerir. Ancak, sayı anlamlı olduğundan diğer görünümlerde görmek istediğinizi anlamadığından el ile eklemeniz gerekir.
Views\Course\Edit.cshtml içinde, 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="form-group">
@Html.LabelFor(model => model.CourseID, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DisplayFor(model => model.CourseID)
</div>
</div>
Düzenleme görünümünde kurs numarası için zaten gizli bir alan (Html.HiddenFor yardımcı) var. Html.LabelFor yardımcısı eklemek, kullanıcı Düzenle sayfasında Kaydet'e tıkladığında kurs numarasının gönderilen verilere eklenmesine neden olmadığından gizli alan gereksinimini ortadan kaldırmaz.
Views\Course\Delete.cshtml and Views\Course\Details.cshtml içinde, bölüm adı başlığını "Ad" yerine "Bölüm" olarak değiştirin ve Başlık alanının önüne bir kurs numarası alanı ekleyin.
<dt>
Department
</dt>
<dd>
@Html.DisplayFor(model => model.Department.Name)
</dd>
<dt>
@Html.DisplayNameFor(model => model.CourseID)
</dt>
<dd>
@Html.DisplayFor(model => model.CourseID)
</dd>
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:
| Değer | Ayar |
|---|---|
| Sayı | 1000 girin. |
| Başlık | Cebir'e girin. |
| Krediler | 4 girin. |
| Bölüm | Matematik'i seçin. |
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ğitmenlere office ekleme sayfası
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:
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Instructor instructor = db.Instructors.Find(id);
if (instructor == null)
{
return HttpNotFound();
}
ViewBag.ID = new SelectList(db.OfficeAssignments, "InstructorID", "Location", instructor.ID);
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)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Instructor instructor = db.Instructors
.Include(i => i.OfficeAssignment)
.Where(i => i.ID == id)
.Single();
if (instructor == null)
{
return HttpNotFound();
}
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, ActionName("Edit")]
[ValidateAntiForgeryToken]
public ActionResult EditPost(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var instructorToUpdate = db.Instructors
.Include(i => i.OfficeAssignment)
.Where(i => i.ID == id)
.Single();
if (TryUpdateModel(instructorToUpdate, "",
new string[] { "LastName", "FirstMidName", "HireDate", "OfficeAssignment" }))
{
try
{
if (String.IsNullOrWhiteSpace(instructorToUpdate.OfficeAssignment.Location))
{
instructorToUpdate.OfficeAssignment = null;
}
db.SaveChanges();
return RedirectToAction("Index");
}
catch (RetryLimitExceededException /* dex */)
{
//Log the error (uncomment dex variable name 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.");
}
}
return View(instructorToUpdate);
}
başvurusu için RetryLimitExceededException bir using deyim gerekir; bunu eklemek için farenizi üzerine RetryLimitExceededExceptiongetirin. Aşağıdaki ileti görüntülenir: 
Olası düzeltmeleri göster'i ve ardından System.Data.Entity.Infrastructure'ı kullanarak

Kod aşağıdakileri yapar:
İmza artık yöntemle aynı
HttpGetolduğundan yöntem adınıEditPostolarak değiştirir (ActionNameözniteliği /Edit/ URL'sinin hala kullanıldığını belirtir).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 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="form-group">
@Html.LabelFor(model => model.OfficeAssignment.Location, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.OfficeAssignment.Location)
@Html.ValidationMessageFor(model => model.OfficeAssignment.Location)
</div>
</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ğitmenler sayfasına kurs ekleme
Eğitmenler herhangi bir sayıda ders verebilir. Şimdi 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; bu da birleştirme tablosundaki yabancı anahtar özelliklerine doğrudan erişiminiz olmadığı anlamına gelir. Bunun yerine, gezinti özelliğine ve gezinti özelliğinden Instructor.Courses varlık ekleyip kaldırırsı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)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Instructor instructor = db.Instructors
.Include(i => i.OfficeAssignment)
.Include(i => i.Courses)
.Where(i => i.ID == id)
.Single();
if (instructor == null)
{
return HttpNotFound();
}
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. EditPost 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, string[] selectedCourses)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var instructorToUpdate = db.Instructors
.Include(i => i.OfficeAssignment)
.Include(i => i.Courses)
.Where(i => i.ID == 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.SaveChanges();
return RedirectToAction("Index");
}
catch (RetryLimitExceededException /* dex */)
{
//Log the error (uncomment dex variable name 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);
}
}
}
}
Yöntem imzası artık yönteminden HttpGet Edit farklıdır, bu nedenle yöntem adı geriden EditPost olarak Editdeğişir.
Görünümde varlık koleksiyonu Course olmadığından model bağlayıcısı gezinti özelliğini otomatik olarak güncelleştiremez Courses . Gezinti özelliğini güncelleştirmek için model bağlayıcısını Courses 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. Bu, açık liste aşırı yüklemesini kullandığınız ve Courses ekleme listesinde olmadığı için 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 ve Kaydet düğmesinin öğesinden önce div aşağıdaki kodu ekleyerek onay kutuları dizisi içeren bir Kurslar alanı ekleyin:
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<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>
</div>
Kodu yapıştırdıktan sonra satır sonları ve girintiler burada olduğu gibi görünmüyorsa, burada gördüğünüz gibi görünmesi için her şeyi el ile düzeltin. Girintinin mükemmel olması gerekmez, ancak @</tr><tr>, @:<td>, @:</td>ve @</tr> satırlarının her birinin gösterildiği gibi tek bir satırda olması gerekir, aksi halde çalışma zamanı hatası alırsınız.
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>Last Name</th>
<th>First Name</th>
<th>Hire Date</th>
<th>Office</th>
<th>Courses</th>
<th></th>
</tr>
Ardından, ofis konumu ayrıntı hücresinin hemen ardından yeni bir ayrıntı hücresi ekleyin:
<td>
@if (item.OfficeAssignment != null)
{
@item.OfficeAssignment.Location
}
</td>
<td>
@{
foreach (var course in item.Courses)
{
@course.CourseID @: @course.Title <br />
}
}
</td>
<td>
@Html.ActionLink("Select", "Index", new { id = item.ID }) |
@Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
@Html.ActionLink("Details", "Details", new { id = item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.ID })
</td>
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: Burada eğitmen kurs 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.
DeleteConfirmed Güncelleştirme
InstructorController.cs yöntemini silin DeleteConfirmed ve aşağıdaki kodu yerine ekleyin.
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Instructor instructor = db.Instructors
.Include(i => i.OfficeAssignment)
.Where(i => i.ID == id)
.Single();
db.Instructors.Remove(instructor);
var department = db.Departments
.Where(d => d.InstructorID == id)
.SingleOrDefault();
if (department != null)
{
department.InstructorID = null;
}
db.SaveChanges();
return RedirectToAction("Index");
}
Bu kod aşağıdaki değişikliği yapar:
- Eğitmen herhangi bir bölümün yöneticisi olarak atandıysa, bu bölümden eğitmen atamasını kaldırır. Bu kod olmadan, bir bölüm için yönetici olarak atanan bir eğitmeni silmeye çalışırsanız bilgi tutarlılığı hatasıyla karşılaşırsınız.
Bu kod, birden çok bölüm için yönetici olarak atanan bir eğitmenin senaryolarını işlemez. Son öğreticide bu senaryonun gerçekleşmesini engelleyen kod ekleyeceksiniz.
Oluştur sayfasına ofis konumu ve kursları ekleme
InstructorController.cs ve HttpPost Create yöntemlerini silin HttpGet ve aşağıdaki kodu yerlerine ekleyin:
public ActionResult Create()
{
var instructor = new Instructor();
instructor.Courses = new List<Course>();
PopulateAssignedCourseData(instructor);
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "LastName,FirstMidName,HireDate,OfficeAssignment" )]Instructor instructor, string[] selectedCourses)
{
if (selectedCourses != null)
{
instructor.Courses = new List<Course>();
foreach (var course in selectedCourses)
{
var courseToAdd = db.Courses.Find(int.Parse(course));
instructor.Courses.Add(courseToAdd);
}
}
if (ModelState.IsValid)
{
db.Instructors.Add(instructor);
db.SaveChanges();
return RedirectToAction("Index");
}
PopulateAssignedCourseData(instructor);
return View(instructor);
}
Bu kod, başlangıçta hiç kurs seçilmemek dışında Düzenleme yöntemleri için gördüklerinize benzer. HttpGet Create yöntemi, seçilen kurslar olabileceğinden değil, görünümde döngü için boş bir koleksiyon sağlamak için foreach yöntemini çağırır PopulateAssignedCourseData (aksi takdirde görünüm kodu null başvuru özel durumu oluşturur).
HttpPost Create yöntemi, seçilen her kursu Doğrulama hatalarını denetleen şablon kodundan önce Kurslar gezinti özelliğine ekler ve yeni eğitmeni veritabanına ekler. Model hataları olsa bile kurslar eklenir, böylece model hataları olduğunda (örneğin, kullanıcı geçersiz bir tarihi anahtarladı), böylece sayfa bir hata iletisiyle yeniden görüntülendiğinde, yapılan tüm kurs seçimleri otomatik olarak geri yüklenir.
Gezinti özelliğine kurs ekleyebilmek için Courses özelliği boş bir koleksiyon olarak başlatmanız gerektiğini fark edin:
instructor.Courses = new List<Course>();
Bunu denetleyici kodunda yapmaya alternatif olarak, aşağıdaki örnekte gösterildiği gibi, eğitmen modelinde özellik alıcısını koleksiyon yoksa otomatik olarak oluşturacak şekilde değiştirerek yapabilirsiniz:
private ICollection<Course> _courses;
public virtual ICollection<Course> Courses
{
get
{
return _courses ?? (_courses = new List<Course>());
}
set
{
_courses = value;
}
}
Özelliğini bu şekilde değiştirirseniz Courses , denetleyicideki açık özellik başlatma kodunu kaldırabilirsiniz.
Views\Instructor\Create.cshtml içinde, işe alma tarihi alanından sonra ve Gönder düğmesinin önüne bir ofis konumu metin kutusu ve kurs onay kutuları ekleyin.
<div class="form-group">
@Html.LabelFor(model => model.OfficeAssignment.Location, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.OfficeAssignment.Location)
@Html.ValidationMessageFor(model => model.OfficeAssignment.Location)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<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>
</div>
Kodu yapıştırdıktan sonra, daha önce Düzenle sayfasında yaptığınız gibi satır sonlarını ve girintiyi düzeltin.
Oluştur sayfasını çalıştırın ve eğitmen ekleyin.
İşlemleri işleme
Temel CRUD İşlevselliği öğreticisinde açıklandığı gibi, Entity Framework varsayılan olarak işlemleri örtük olarak uygular. Daha fazla denetime ihtiyacınız olan senaryolar için (örneğin, bir işleme Entity Framework dışında yapılan işlemleri dahil etmek istiyorsanız), bkz . MSDN'de İşlemlerle Çalışma.
Kodu alma
Ek kaynaklar
Diğer Entity Framework kaynaklarına bağlantılar ASP.NET Veri Erişimi - Önerilen Kaynaklar'da bulunabilir.
Sonraki adım
Bu öğreticide şunları yaptınız:
- Özelleştirilmiş kurs sayfaları
- Eğitmenler sayfasına office eklendi
- Eğitmenler sayfasına kurslar eklendi
- Güncelleştirilmiş DeleteConfirmed
- Oluştur sayfasına ofis konumu ve kurslar eklendi
Zaman uyumsuz programlama modelini uygulamayı öğrenmek için sonraki makaleye ilerleyin.