Öğretici: CRUD İşlevselliği Uygulama - ASP.NET MVC ile EF Core
Önceki öğreticide, LocalDB'de veri depoları ve yerel veritabanı Entity Framework verileri SQL Server bir MVC uygulaması oluşturdun. Bu öğreticide, MVC yapı iskelesi tarafından denetleyicilerde ve görünümlerde sizin için otomatik olarak oluşturduğu CRUD (oluşturma, okuma, güncelleştirme, silme) kodunu gözden geçirecek ve özelleştirebilirsiniz.
Not
Denetleyiciniz ile veri erişim katmanı arasında bir soyutlama katmanı oluşturmak için depo deseninin uygulanması yaygın bir uygulamadır. Bu öğreticileri basit tutmak ve bu öğreticilerin kendisini kullanmayı Entity Framework odaklı olmak için depoları kullanmazlar. EF ile depolar hakkında bilgi için bu serinin son öğreticiye bakın.
Bu öğreticide şunları yaptınız:
- Ayrıntılar sayfasını özelleştirme
- Oluştur sayfasını güncelleştirme
- Düzenle sayfasını güncelleştirme
- Sil sayfasını güncelleştirme
- Veritabanı bağlantılarını kapatma
Önkoşullar
Ayrıntılar sayfasını özelleştirme
Öğrenciler Dizini sayfasının iskelesi olan kod, bir koleksiyona sahip olduğundan Enrollments özelliği dışarıda bıraktı. Ayrıntılar sayfasında, koleksiyonun içeriğini bir HTML tablosunda görüntüleyebilirsiniz.
Controllers/StudentsController.cs içinde Ayrıntılar görünümüne ilişkin eylem yöntemi, FirstOrDefaultAsync tek bir varlığı almak için yöntemini Student kullanır. çağıran kod Include ekleyin. ThenInclude, AsNoTracking ve yöntemleri, aşağıdaki vurgulanan kodda gösterildiği gibi.
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var student = await _context.Students
.Include(s => s.Enrollments)
.ThenInclude(e => e.Course)
.AsNoTracking()
.FirstOrDefaultAsync(m => m.ID == id);
if (student == null)
{
return NotFound();
}
return View(student);
}
ve yöntemleri bağlamın gezinti özelliğini ve her kayıt içinde Include gezinti özelliğini ThenInclude Student.Enrollments Enrollment.Course yüklemesi için neden olur. İlgili verileri okuma öğreticisinde bu yöntemler hakkında daha fazla bilgi edinebilirsiniz.
yöntemi, döndürülen varlıkların geçerli bağlamın yaşam süresinde AsNoTracking güncelleştirilmez olduğu senaryolarda performansı artırır. Bu öğreticinin sonunda hakkında AsNoTracking daha fazla bilgi edin bulacaksınız.
Veri yönlendirme
yöntemine geçirilen anahtar değeri Details yol verilerinden gelir. Yönlendirme verileri, model bağlayıcının URL'nin bir segmentinde bulduğu verilerdir. Örneğin, varsayılan yol denetleyici, eylem ve kimlik kesimlerini belirtir:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
Aşağıdaki URL'de, varsayılan yol Eğitmeni denetleyici olarak, eylem olarak Dizin'i ve kimlik olarak 1'i eşler; Bunlar rota veri değerleridir.
http://localhost:1230/Instructor/Index/1?courseID=2021
URL'nin son bölümü ("?courseID=2021") bir sorgu dizesi değeridir. Model bağlayıcısı, kimlik değerini sorgu dizesi değeri olarak iletirsanız Index id yöntem parametresine de iletir:
http://localhost:1230/Instructor/Index?id=1&CourseID=2021
Dizin sayfasında köprü URL'leri görünümdeki etiket yardımcı deyimleri tarafından Razor oluşturulur. Aşağıdaki Razor kodda parametresi id varsayılan yol ile eştir ve yol id verilerine eklenir.
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a>
Bu, 6 olduğunda aşağıdaki item.ID HTML'yi üretir:
<a href="/Students/Edit/6">Edit</a>
Aşağıdaki Razor studentID kodda, varsayılan yolda bir parametreyle eşleşmez, bu nedenle sorgu dizesi olarak eklenir.
<a asp-action="Edit" asp-route-studentID="@item.ID">Edit</a>
Bu, 6 olduğunda aşağıdaki item.ID HTML'yi üretir:
<a href="/Students/Edit?studentID=6">Edit</a>
Etiket yardımcıları hakkında daha fazla bilgi için bkz. ASP.NET Core etiket yardımcıları .
Ayrıntılar görünümüne kayıt ekleme
Views/Students/Details.cshtml dosyasını açın. Aşağıdaki örnekte gösterildiği DisplayNameFor DisplayFor gibi, her alan ve yardımcıları kullanılarak görüntülenir:
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.LastName)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.LastName)
</dd>
Son alandan sonra ve kapanış etiketinin hemen </dl> önünde, kayıtların listesini görüntülemek için aşağıdaki kodu ekleyin:
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Enrollments)
</dt>
<dd class="col-sm-10">
<table class="table">
<tr>
<th>Course Title</th>
<th>Grade</th>
</tr>
@foreach (var item in Model.Enrollments)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Course.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.Grade)
</td>
</tr>
}
</table>
</dd>
Kodu yapıştırırken kod girintileme yanlışsa, düzeltmek için CTRL-K-D tuşlarına basın.
Bu kod gezinti özelliğinde varlıklar arasında Enrollments döngüye alar. Her kayıt için kurs başlığı ve not görüntülenir. Kurs başlığı, Kayıtlar varlığının gezinti özelliğinde depolanan Course Kurs varlığından alınır.
Uygulamayı çalıştırın, Öğrenciler sekmesini seçin ve bir öğrencinin Ayrıntılar bağlantısına tıklayın. Seçilen öğrenciye yönelik derslerin ve notların listesini görüyorsunuz:

Oluştur sayfasını güncelleştirme
StudentsController.cs içinde, bir try-catch bloğu ekleyerek ve özniteliğinden kimliği kaldırarak HttpPost Create yöntemini Bind değiştirebilirsiniz.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(
[Bind("EnrollmentDate,FirstMidName,LastName")] Student student)
{
try
{
if (ModelState.IsValid)
{
_context.Add(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.
ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists " +
"see your system administrator.");
}
return View(student);
}
Bu kod, MVC model ASP.NET Core tarafından oluşturulan Öğrenci varlığını Öğrenciler varlık kümesine ekler ve ardından değişiklikleri veritabanına kaydeder. (Model bağlayıcısı, bir form tarafından gönderilen verilerle çalışmayı kolaylaştıran ASP.NET Core MVC işlevini ifade eder; model bağlayıcısı, gönderilen form değerlerini CLR türlerine dönüştürür ve parametrelerde eylem yöntemine iletir. Bu durumda model bağlayıcısı, Form koleksiyonundan özellik değerlerini kullanarak sizin için bir Öğrenci varlığı örneği verir.)
Id, ID satır Bind eklenirken otomatik olarak ayarlanacak birincil SQL Server değeri olduğundan özniteliğinden kaldırdınız. Kullanıcıdan gelen giriş, kimlik değerini ayarlamaz.
özniteliği dışında, iskelesi yapılmış kodda tek Bind değişiklik try-catch bloğudur. Değişiklikler kaydedilirken 'den DbUpdateException türeten bir özel durum yakalanırsa, genel bir hata iletisi görüntülenir. DbUpdateException özel durumlara bazen programlama hatası yerine uygulamanın dışından bir neden olur, bu nedenle kullanıcının yeniden denemesi önerilir. Bu örnekte uygulanmamış olsa da üretim kalitesindeki bir uygulama özel durumu günlüğe kaydedilir. Daha fazla bilgi için İzleme ve Telemetri (Azure ile Bulut Uygulamalarını Real-World) bölümündeki Öngörüiçin günlük bölümüne bakın.
özniteliği, ValidateAntiForgeryToken siteler arası istek sahtecilik (CSRF) saldırılarını önlemeye yardımcı olur. Belirteç, FormTagHelper tarafından görünüme otomatik olarak eklenir ve form kullanıcı tarafından gönderilirken eklenir. Belirteç özniteliği tarafından ValidateAntiForgeryToken doğrulanır. Daha fazla bilgi için bkz. ASP.NET Core siteler arası Istek sahteciliği (XSRF/CSRF) saldırılarını önle.
Fazla posta ile ilgili güvenlik notu
İskeleli kodun yöntemine dahil olduğu öznitelik, oluşturma senaryolarında aşırı Bind Create postaya karşı korumanın bir yoludur. Örneğin, Öğrenci varlığının bu Secret web sayfasının ayarlamayı istemeyebilirsiniz bir özelliği olduğunu varsayalım.
public class Student
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public string Secret { get; set; }
}
Web sayfasında bir alanınız yoksa bile, bilgisayar korsanı Fiddler gibi bir araç kullanabilir veya form değeri oluşturmak için Secret javascript Secret yazabilir. Öznitelik, model bağlayıcının Student örneği oluşturduğunda kullandığı alanları sınırlamadan, model bağlayıcı bu form değerini alır ve Öğrenci varlık örneğini oluşturmak Bind Secret için kullanır. Ardından bilgisayar korsanı form alanı için Secret belirtilen değer veritabanınıza güncelleştirilir. Aşağıdaki görüntüde, gönderilen form değerlerine alanını ("OverPost" değeriyle) ekleyen Fiddler Secret aracı yer alır.

"OverPost" değeri daha sonra eklenen satırın özelliğine başarıyla eklenir, ancak web sayfasının bu özelliği ayarlamayı hiç Secret amaçlayamasanız da.
Düzenleme senaryolarında, varlığı önce veritabanından okuyarak ve ardından çağırarak, açık izin verilen özellikler listesini geçerek aşırı TryUpdateModel postayı önleyemezsiniz. Bu öğreticilerde bu yöntem kullanılır.
Birçok geliştirici tarafından tercih edilen fazla postayı önlemenin alternatif bir yolu, model bağlama ile varlık sınıfları yerine modelleri görüntülemektir. Yalnızca görünüm modelinde güncelleştirmek istediğiniz özellikleri dahil etmek. MVC model bağlayıcısı tamamlandığında, isteğe bağlı olarak AutoMapper gibi bir araç kullanarak görünüm modeli özelliklerini varlık örneğine kopyalayın. Durumunu olarak ayarlamak için varlık örneğinde kullanın ve ardından görünüm modeline dahil edilen her varlık _context.Entry Unchanged Property("PropertyName").IsModified özelliğinde true olarak ayarlayın. Bu yöntem hem düzenleme hem de oluşturma senaryolarında çalışır.
Oluştur sayfasını test edin
Views/Students/Create.cshtml kodu, her alan için , ve (doğrulama iletileri label input span için) etiket yardımcılarını kullanır.
Uygulamayı çalıştırın, Öğrenciler sekmesini seçin ve Yeni Oluştur'a tıklayın.
Adları ve tarihi girin. Tarayıcınız bunu yapmanıza izin verdiyse geçersiz bir tarih girmeyi deneyin. (Bazı tarayıcılar sizi tarih seçici kullanmaya zorlar.) Ardından hata iletisini görmek için Oluştur'a tıklayın.

Bu, varsayılan olarak elde varsayılan olarak sunucu tarafı doğrulamadır; Sonraki bir öğreticide, istemci tarafı doğrulama için kod oluşturan özniteliklerin nasıl ekli olduğunu da göreceğiz. Aşağıdaki vurgulanmış kod, yönteminde model doğrulama denetimi Create gösterir.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(
[Bind("EnrollmentDate,FirstMidName,LastName")] Student student)
{
try
{
if (ModelState.IsValid)
{
_context.Add(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.
ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists " +
"see your system administrator.");
}
return View(student);
}
Tarihi geçerli bir değerle değiştirin ve Yeni öğrenciyi Dizin sayfasında görmek için Oluştur'a tıklayın.
Düzenle sayfasını güncelleştirme
StudentController.cs içinde HttpGet yöntemi (özniteliği olmayan yöntem), yönteminde gördüğümüz gibi seçili Öğrenci varlığını almak Edit HttpPost için yöntemini FirstOrDefaultAsync Details kullanır. Bu yöntemi değiştirmek zorunda değildir.
Önerilen HttpPost Düzenleme kodu: Okuma ve güncelleştirme
HttpPost Edit eylem yöntemini aşağıdaki kodla değiştirin.
[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EditPost(int? id)
{
if (id == null)
{
return NotFound();
}
var studentToUpdate = await _context.Students.FirstOrDefaultAsync(s => s.ID == id);
if (await TryUpdateModelAsync<Student>(
studentToUpdate,
"",
s => s.FirstMidName, s => s.LastName, s => s.EnrollmentDate))
{
try
{
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.)
ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists, " +
"see your system administrator.");
}
}
return View(studentToUpdate);
}
Bu değişiklikler, aşırı postayı önlemek için en iyi güvenlik uygulamasıdır. yapı iskelesi bir öznitelik oluşturdu ve model bağlayıcısı tarafından oluşturulan varlığı Bind bayrağıyla varlık kümesine Modified ekledi. özniteliği, parametresinde listelenmiyor olan alanlardaki önceden mevcut olan verileri temizleyene kadar birçok senaryo Bind için bu kod Include önerilmez.
Yeni kod, mevcut varlığı okur ve TryUpdateModel alınan varlıktaki alanları, postalanan form verilerinde Kullanıcı girişine göregüncelleştirmek için çağırır. Entity Framework otomatik değişiklik izleme, Modified form girişi tarafından değiştirilen alanlardaki bayrağı ayarlar. SaveChangesyöntemi çağrıldığında, Entity Framework veritabanı satırını güncelleştirmek için SQL deyimler oluşturur. Eşzamanlılık çakışmaları yok sayılır ve yalnızca Kullanıcı tarafından güncellenen tablo sütunları veritabanında güncelleştirilir. (Sonraki bir öğretici eşzamanlılık çakışmalarının nasıl işleneceğini gösterir.)
Fazla nakletmeyi önleyen en iyi yöntem olarak, düzenleme sayfası tarafından güncelleştirilebilir olmasını istediğiniz alanlar TryUpdateModel parametrelerde belirtilir. (Parametre listesindeki alanlar listesinden önceki boş dize, form alanları adlarıyla kullanılacak bir ön ek içindir.) Şu anda koruduğunuz ek alan yok, ancak model cildin bağlamasını istediğiniz alanları listelemek, gelecekte veri modeline alanlar eklerseniz, bunları buraya açıkça eklemeene kadar otomatik olarak korunur.
Bu değişikliklerin sonucu olarak, HttpPost yönteminin yöntem imzası Edit HttpGet Edit yöntemiyle aynıdır; bu nedenle, yöntemi yeniden adlandırdınız EditPost .
Alternatif HttpPost düzenleme kodu: oluşturma ve iliştirme
Önerilen HttpPost düzenleme kodu yalnızca değiştirilen sütunların güncelleştirilmesini sağlar ve model bağlama dahil etmek istemediğiniz özelliklerde verileri korur. Ancak, ilk okuma yaklaşımı, fazladan bir veritabanı okuması gerektirir ve eşzamanlılık çakışmalarını işlemek için daha karmaşık kod oluşmasına neden olabilir. Diğer bir seçenek de model cildi tarafından oluşturulan bir varlığı EF bağlamına eklemektir ve değiştirildi olarak işaretler. (Projenizi bu kodla güncelleştirmeyin, yalnızca isteğe bağlı bir yaklaşımı göstermek için gösterilir.)
public async Task<IActionResult> Edit(int id, [Bind("ID,EnrollmentDate,FirstMidName,LastName")] Student student)
{
if (id != student.ID)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.)
ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists, " +
"see your system administrator.");
}
}
return View(student);
}
Web sayfası kullanıcı arabirimi varlıktaki tüm alanları içerdiğinde ve bunlardan herhangi birini güncelleştirebilmeniz durumunda bu yaklaşımı kullanabilirsiniz.
Yapı iskelesi kodu, oluşturma ve iliştirme yaklaşımını kullanır, ancak yalnızca DbUpdateConcurrencyException özel durumları yakalar ve 404 hata kodlarını döndürür. Gösterilen örnek herhangi bir veritabanı güncelleştirme özel durumunu yakalar ve bir hata iletisi görüntüler.
Varlık durumları
Veritabanı bağlamı, bellekteki varlıkların veritabanında karşılık gelen satırlarıyla eşitlenmiş olup olmadığını izler ve bu bilgiler yöntemi çağırdığınızda ne olacağını belirler SaveChanges . Örneğin, yöntemine yeni bir varlık geçirdiğinizde Add , bu varlığın durumu olarak ayarlanır Added . sonra, SaveChanges yöntemini çağırdığınızda veritabanı bağlamı bir SQL ınsert komutu yayınlar.
Bir varlık aşağıdaki durumlardan birinde olabilir:
Added. Varlık veritabanında henüz yok.SaveChangesYöntemi BIR INSERT ifadesini yayınlar.Unchanged. Yöntemi tarafından bu varlıkla ilgili hiçbir şey yapılması gerekmezSaveChanges. Veritabanından bir varlık okuduğunuzda, varlık bu durumla başlar.Modified. Varlığın özellik değerlerinin bazıları veya tümü değiştirildi.SaveChangesYöntemi BIR Update ifadesini yayınlar.Deleted. Varlık silinmek üzere işaretlendi.SaveChangesYöntemi BIR DELETE ifadesini yayınlar.Detached. Varlık, veritabanı bağlamı tarafından izlenmiyor.
Bir masaüstü uygulamasında durum değişiklikleri genellikle otomatik olarak ayarlanır. Bir varlığı okur ve bazı özellik değerlerinde değişiklik yaparsınız. Bu, varlık durumunun otomatik olarak olarak değiştirilmesine neden olur Modified . sonra SaveChanges , Entity Framework yalnızca değiştirdiğiniz gerçek özellikleri güncelleştiren bir SQL UPDATE bildirisi oluşturur.
Bir Web uygulamasında, DbContext Başlangıçta bir varlığı okur ve bir sayfa işlendikten sonra düzenlenecek verilerini görüntüler. HttpPost Edit eylemi yöntemi çağrıldığında yeni bir Web isteği yapılır ve yeni bir örneğine sahip olursunuz DbContext . Varlığı bu yeni bağlamda yeniden okuduğunuzda masaüstü işleme benzetimi yapılır.
Ancak, fazladan okuma işlemi yapmak istemiyorsanız, model Ciltçi tarafından oluşturulan varlık nesnesini kullanmanız gerekir. Bunu yapmanın en kolay yolu, daha önce gösterilen diğer HttpPost düzenleme kodunda yapıldığı gibi varlık durumunun değiştirilme olarak ayarlanmanız olur. Ardından, öğesini çağırdığınızda, SaveChanges bağlam hangi özellikleri değiştireceğimizi bilen bir yolu olmadığından, Entity Framework veritabanı satırının tüm sütunlarını günceller.
okuma-ilk yaklaşımının önüne geçmek istiyorsanız, ancak SQL UPDATE bildiriminin yalnızca kullanıcının gerçekten değiştirdiği alanları güncelleştirmesini istiyorsanız, kod daha karmaşıktır. HttpPost yöntemi çağrıldığında kullanılabilir olmaları için özgün değerleri bir şekilde (örneğin, gizli alanları kullanarak) kaydetmeniz gerekir Edit . Ardından özgün değerleri kullanarak bir öğrenci varlığı oluşturabilir, Attach yöntemi varlığın orijinal sürümüyle çağırabilir, varlığın değerlerini yeni değerlerle güncelleştirebilir ve ardından öğesini çağırabilirsiniz SaveChanges .
Düzenleme sayfasını test etme
Uygulamayı çalıştırın, öğrenciler sekmesini seçin ve köprü Düzenle ' ye tıklayın.

Bazı verileri değiştirin ve Kaydet' e tıklayın. Dizin sayfası açılır ve değiştirilen verileri görürsünüz.
Silme sayfasını Güncelleştir
Studentcontroller. cs dosyasında, HttpGet yöntemi için şablon kodu, Delete FirstOrDefaultAsync Ayrıntılar ve düzenleme yöntemlerinde gördüğünüz gibi seçili öğrenci varlığını almak için yöntemini kullanır. Ancak, çağrı başarısız olursa özel bir hata iletisi uygulamak için SaveChanges Bu yönteme ve buna karşılık gelen görünüme bazı işlevler eklersiniz.
Güncelleştirme ve oluşturma işlemleri için gördüğünüz gibi silme işlemleri için iki eylem yöntemi gerekir. GET isteğine yanıt olarak çağrılan yöntem, kullanıcıya silme işlemini onaylama veya iptal etme şansı veren bir görünüm görüntüler. Kullanıcı onu onayladığında, bir POST isteği oluşturulur. Bu durumda, HttpPost Delete yöntemi çağrılır ve bu yöntem aslında silme işlemini gerçekleştirir.
DeleteVeritabanı güncelleştirilirken oluşabilecek hataları işlemek Için HttpPost yöntemine bir try-catch bloğu ekleyeceksiniz. Bir hata oluşursa, HttpPost Delete yöntemi bir hata oluştuğunu gösteren bir parametre geçirerek HttpGet Delete yöntemini çağırır. HttpGet Delete yöntemi daha sonra hata iletisiyle birlikte onay sayfasını yeniden görüntüler ve kullanıcıya iptal etmek veya yeniden denemek için bir fırsat verir.
HttpGet Delete eylem yöntemini, hata raporlamayı yöneten aşağıdaki kodla değiştirin.
public async Task<IActionResult> Delete(int? id, bool? saveChangesError = false)
{
if (id == null)
{
return NotFound();
}
var student = await _context.Students
.AsNoTracking()
.FirstOrDefaultAsync(m => m.ID == id);
if (student == null)
{
return NotFound();
}
if (saveChangesError.GetValueOrDefault())
{
ViewData["ErrorMessage"] =
"Delete failed. Try again, and if the problem persists " +
"see your system administrator.";
}
return View(student);
}
Bu kod, bir yöntemin değişiklikleri kaydetme hatasından sonra döndürülüp çağrılmadığını belirten isteğe bağlı bir parametresini kabul eder. HttpGet Delete yöntemi önceki bir hata olmadan çağrıldığında bu parametre false 'tur. DeleteBir veritabanı güncelleştirme hatasına yanıt olarak HttpPost yöntemi tarafından çağrıldığında, parametresi true olur ve görünüme bir hata mesajı geçirilir.
HttpPost silme için ilk okuma yaklaşımı
HttpPost Delete eylemi yöntemini (adlı), DeleteConfirmed gerçek silme işlemini gerçekleştiren ve tüm veritabanı güncelleştirme hatalarını yakalayan aşağıdaki kodla değiştirin.
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var student = await _context.Students.FindAsync(id);
if (student == null)
{
return RedirectToAction(nameof(Index));
}
try
{
_context.Students.Remove(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.)
return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true });
}
}
Bu kod seçili varlığı alır, ardından Remove varlığın durumunu olarak ayarlamak için yöntemini çağırır Deleted . SaveChangesçağrıldığında, bir SQL DELETE komutu oluşturulur.
HttpPost silme için Oluştur ve Ekle yaklaşımı
yüksek hacimli bir uygulamadaki performansı artırmak bir önceliktir, yalnızca birincil anahtar değerini kullanarak bir öğrenci varlığını örnekleyerek ve ardından varlık durumunu olarak ayarlayarak gereksiz bir SQL sorgusunun oluşmasını önleyebilirsiniz Deleted . Bu, Entity Framework varlığı silmek için ihtiyaç duymaktadır. (Bu kodu projenize yerleştirmeyin; bir alternatif göstermek de yeterlidir.)
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
try
{
Student studentToDelete = new Student() { ID = id };
_context.Entry(studentToDelete).State = EntityState.Deleted;
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.)
return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true });
}
}
Varlığın de silinmesi gereken ilgili veriler varsa, veritabanında Cascade silmenin yapılandırıldığından emin olun. Varlık silme yaklaşımıyla EF, silinecek ilgili varlıkların olduğunu fark etmeyebilir.
Silme görünümünü Güncelleştir
Görünümler/öğrenci/delete. cshtml' de, aşağıdaki örnekte gösterildiği gibi, H2 başlığı ve H3 başlığı arasına bir hata iletisi ekleyin:
<h2>Delete</h2>
<p class="text-danger">@ViewData["ErrorMessage"]</p>
<h3>Are you sure you want to delete this?</h3>
Uygulamayı çalıştırın, öğrenciler sekmesini seçin ve bir Delete köprüsüne tıklayın:

Sil'e tıklayın. Dizin sayfası, silinen öğrenci olmadan görüntülenir. (Eşzamanlılık öğreticisinde işlem içinde kodu işleme hatası hakkında bir örnek görürsünüz.)
Veritabanı bağlantılarını kapat
Bir veritabanı bağlantısının tuttuğu kaynakları boşaltmak için bağlam örneği, bununla işiniz bittiğinde en kısa sürede atılmalıdır. ASP.NET Core yerleşik bağımlılık ekleme , sizin için bu görevi gerçekleştirir.
Startup. cs dosyasında, sınıfı ASP.NET Core DI kapsayıcısında sağlamak için adddbcontext genişletme yöntemini çağırın DbContext . Bu yöntem, hizmet ömrünü Scoped Varsayılan olarak olarak ayarlar. Scoped , Web isteği ömrü boyunca saatle çakışan bağlam nesnesi yaşam süresi anlamına gelir ve Dispose Bu yöntem Web isteğinin sonunda otomatik olarak çağrılır.
İşlemleri işle
Entity Framework, varsayılan olarak işlemleri örtülü olarak uygular. Birden çok satır veya tabloda değişiklik yaptığınız senaryolarda SaveChanges Entity Framework, sonra da tüm değişikliklerinizin başarılı veya tümünün başarısız olduğundan emin olur. Önce bazı değişiklikler yapıldıktan sonra bir hata oluşursa, bu değişiklikler otomatik olarak geri alınır. Daha fazla denetime ihtiyacınız olan senaryolar için--örneğin, işlem içinde Entity Framework dışında yapılan işlemleri eklemek istiyorsanız, bkz. işlemler.
İzleme sorguları yok
Bir veritabanı bağlamı tablo satırları aldığında ve bunları temsil eden varlık nesneleri oluşturduğunda, varsayılan olarak, bellekteki varlıkların veritabanında bulunan verilerle eşitlenmiş olup olmadığını izler. Bellekteki veriler önbellek olarak davranır ve bir varlığı güncelleştirdiğinizde kullanılır. Bağlam örnekleri genellikle kısa süreli olduğundan (her istek için yeni bir tane oluşturulup bırakıldığı) ve bir varlığı okuyan bağlam genellikle bu varlık yeniden kullanılmadan önce atıldığından, bu önbelleğe alma işlemi bir Web uygulamasında genellikle gereksizdir.
Yöntemini çağırarak, bellekteki varlık nesnelerinin izlenmesini devre dışı bırakabilirsiniz AsNoTracking . Bunu yapmak isteyebileceğiniz tipik senaryolar şunlardır:
Bağlam ömrü boyunca herhangi bir varlığı güncelleştirmeniz gerekmez ve ayrı sorgular tarafından alınan varlıklarla birlikte gezinti özelliklerini otomatik olarak yüklemekiçin EF 'e ihtiyacınız yoktur. Bu koşullar genellikle denetleyicinin HttpGet eylem yöntemlerinde karşılanır.
Büyük miktarda veri alan bir sorgu çalıştırıyorsunuz ve döndürülen verilerin yalnızca küçük bir kısmı güncelleştiriliyor. Büyük sorgu için izlemeyi devre dışı bırakmak ve daha sonra güncellenmesi gereken birkaç varlık için bir sorgu çalıştırmak daha verimli olabilir.
Güncelleştirmek için bir varlık eklemek istiyor ancak daha önce aynı varlığı farklı bir amaç için aldısınız. Varlık zaten veritabanı bağlamı tarafından izlenmektedir, değiştirmek istediğiniz varlığı ek olamazsınız. Bu durumu işlemenin bir yolu, önceki
AsNoTrackingsorguda çağrısı yapmaktır.
Daha fazla bilgi için bkz. İzleme ve İzleme Yok.
Kodu alma
Tamamlanan uygulamayı indirme veya görüntüleme.
Sonraki adımlar
Bu öğreticide şunları yaptınız:
- Ayrıntılar sayfası özelleştirildi
- Oluştur sayfası güncelleştirildi
- Düzenle sayfası güncelleştirildi
- Sil sayfası güncelleştirildi
- Kapalı veritabanı bağlantıları
Sıralama, filtreleme ve sayfalama ekleyerek Dizin sayfasının işlevselliğini genişletmeyi öğrenmek için sonraki öğreticiye ilerleyin.