Bagikan melalui


Skenario Kerangka Kerja Entitas Tingkat Lanjut untuk Aplikasi Web MVC (10 dari 10)

oleh Tom Dykstra

Aplikasi web sampel Contoso University menunjukkan cara membuat aplikasi ASP.NET MVC 4 menggunakan Entity Framework 5 Code First dan Visual Studio 2012. Untuk informasi tentang seri tutorial, lihat tutorial pertama dalam seri ini.

Catatan

Jika Anda mengalami masalah yang tidak dapat Anda atasi, unduh bab yang telah selesai dan coba reprodurasi masalah Anda. Anda umumnya dapat menemukan solusi untuk masalah dengan membandingkan kode Anda dengan kode yang telah selesai. Untuk beberapa kesalahan umum dan cara mengatasinya, lihat Kesalahan dan Solusi.

Dalam tutorial sebelumnya Anda menerapkan repositori dan unit pola kerja. Tutorial ini mencakup topik-topik berikut:

  • Melakukan kueri SQL mentah.
  • Melakukan kueri tanpa pelacakan.
  • Memeriksa kueri yang dikirim ke database.
  • Bekerja dengan kelas proksi.
  • Menonaktifkan deteksi perubahan otomatis.
  • Menonaktifkan validasi saat menyimpan perubahan.
  • Kesalahan dan Mengatasi Masalah

Untuk sebagian besar topik ini, Anda akan bekerja dengan halaman yang sudah Anda buat. Untuk menggunakan SQL mentah untuk melakukan pembaruan massal, Anda akan membuat halaman baru yang memperbarui jumlah kredit semua kursus dalam database:

Cuplikan layar memperlihatkan halaman awal Perbarui Kredit Kursus. Angka 2 dimasukkan di bidang teks.

Dan untuk menggunakan kueri tanpa pelacakan, Anda akan menambahkan logika validasi baru ke halaman Edit Departemen:

Cuplikan layar yang memperlihatkan halaman Edit Departemen Universitas Contoso dengan pesan kesalahan administrator duplikat.

Melakukan Kueri SQL Mentah

API Pertama Kode Kerangka Kerja Entitas menyertakan metode yang memungkinkan Anda meneruskan perintah SQL langsung ke database. Anda memiliki opsi berikut:

  • DbSet.SqlQuery Gunakan metode untuk kueri yang mengembalikan jenis entitas. Objek yang dikembalikan harus dari jenis yang diharapkan oleh DbSet objek, dan secara otomatis dilacak oleh konteks database kecuali Anda menonaktifkan pelacakan. (Lihat bagian berikut tentang metode . AsNoTracking )
  • Database.SqlQuery Gunakan metode untuk kueri yang mengembalikan jenis yang bukan entitas. Data yang dikembalikan tidak dilacak oleh konteks database, bahkan jika Anda menggunakan metode ini untuk mengambil jenis entitas.
  • Gunakan Database.ExecuteSqlCommand untuk perintah non-kueri.

Salah satu keuntungan menggunakan Kerangka Kerja Entitas adalah menghindari pengikatan kode Anda terlalu dekat dengan metode penyimpanan data tertentu. Ini dilakukan dengan menghasilkan kueri dan perintah SQL untuk Anda, yang juga membebaskan Anda dari harus menulisnya sendiri. Tetapi ada skenario luar biasa ketika Anda perlu menjalankan kueri SQL tertentu yang telah Anda buat secara manual, dan metode ini memungkinkan Anda untuk menangani pengecualian tersebut.

Seperti yang selalu benar ketika Anda menjalankan perintah SQL dalam aplikasi web, Anda harus mengambil tindakan pencegahan untuk melindungi situs Anda dari serangan injeksi SQL. Salah satu cara untuk melakukannya adalah dengan menggunakan kueri berparameter untuk memastikan bahwa string yang dikirimkan oleh halaman web tidak dapat ditafsirkan sebagai perintah SQL. Dalam tutorial ini Anda akan menggunakan kueri berparameter saat mengintegrasikan input pengguna ke dalam kueri.

Memanggil Kueri yang Mengembalikan Entitas

Misalkan Anda ingin GenericRepository kelas memberikan fleksibilitas pemfilteran dan pengurutan tambahan tanpa mengharuskan Anda membuat kelas turunan dengan metode tambahan. Salah satu cara untuk mencapainya adalah dengan menambahkan metode yang menerima kueri SQL. Anda kemudian dapat menentukan segala jenis pemfilteran atau pengurutan yang Anda inginkan di pengontrol, seperti Where klausa yang bergantung pada gabungan atau subkueri. Di bagian ini Anda akan melihat cara menerapkan metode seperti itu.

GetWithRawSql Buat metode dengan menambahkan kode berikut ke GenericRepository.cs:

public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
    return dbSet.SqlQuery(query, parameters).ToList();
}

Dalam CourseController.cs, panggil metode baru dari Details metode , seperti yang ditunjukkan dalam contoh berikut:

public ActionResult Details(int id)
{
    var query = "SELECT * FROM Course WHERE CourseID = @p0";
    return View(unitOfWork.CourseRepository.GetWithRawSql(query, id).Single());
}

Dalam hal ini Anda dapat menggunakan GetByID metode , tetapi Anda menggunakan GetWithRawSql metode untuk memverifikasi bahwa GetWithRawSQL metode berfungsi.

Jalankan halaman Detail untuk memverifikasi bahwa kueri pilih berfungsi (pilih tab Kursus lalu Detail untuk satu kursus).

Cuplikan layar yang memperlihatkan halaman Detail Universitas Contoso.

Memanggil Kueri yang Mengembalikan Tipe Objek Lainnya

Sebelumnya Anda membuat kisi statistik siswa untuk halaman Tentang yang menunjukkan jumlah siswa untuk setiap tanggal pendaftaran. Kode yang melakukan ini di HomeController.cs menggunakan LINQ:

var data = from student in db.Students
           group student by student.EnrollmentDate into dateGroup
           select new EnrollmentDateGroup()
           {
               EnrollmentDate = dateGroup.Key,
               StudentCount = dateGroup.Count()
           };

Misalkan Anda ingin menulis kode yang mengambil data ini langsung di SQL daripada menggunakan LINQ. Untuk melakukannya, Anda perlu menjalankan kueri yang mengembalikan sesuatu selain objek entitas, yang berarti Anda perlu menggunakan metode .Database.SqlQuery

Dalam HomeController.cs, ganti pernyataan LINQ dalam About metode dengan kode berikut:

var query = "SELECT EnrollmentDate, COUNT(*) AS StudentCount "
    + "FROM Person "
    + "WHERE EnrollmentDate IS NOT NULL "
    + "GROUP BY EnrollmentDate";
var data = db.Database.SqlQuery<EnrollmentDateGroup>(query);

Jalankan halaman Tentang. Ini menampilkan data yang sama seperti sebelumnya.

Cuplikan layar yang memperlihatkan halaman Contoso University About.

Memanggil Kueri Pembaruan

Misalkan administrator Contoso University ingin dapat melakukan perubahan massal dalam database, seperti mengubah jumlah kredit untuk setiap kursus. Jika universitas memiliki sejumlah besar kursus, tidak efisien untuk mengambil semuanya sebagai entitas dan mengubahnya satu per satu. Di bagian ini, Anda akan menerapkan halaman web yang memungkinkan pengguna menentukan faktor untuk mengubah jumlah kredit untuk semua kursus, dan Anda akan membuat perubahan dengan menjalankan pernyataan SQL UPDATE . Halaman web akan terlihat seperti ilustrasi berikut:

Cuplikan layar yang memperlihatkan halaman awal Perbarui Kredit Kursus. Angka 2 dimasukkan di bidang teks.

Dalam tutorial sebelumnya Anda menggunakan repositori generik untuk membaca dan memperbarui Course entitas di Course pengontrol. Untuk operasi pembaruan massal ini, Anda perlu membuat metode repositori baru yang tidak ada di repositori generik. Untuk melakukannya, Anda akan membuat kelas khusus CourseRepository yang berasal dari GenericRepository kelas .

Di folder DAL, buat CourseRepository.cs dan ganti kode yang ada dengan kode berikut:

using System;
using ContosoUniversity.Models;

namespace ContosoUniversity.DAL
{
    public class CourseRepository : GenericRepository<Course>
    {
        public CourseRepository(SchoolContext context)
            : base(context)
        {
        }

        public int UpdateCourseCredits(int multiplier)
        {
            return context.Database.ExecuteSqlCommand("UPDATE Course SET Credits = Credits * {0}", multiplier);
        }

    }
}

Di UnitOfWork.cs, ubah Course jenis repositori dari GenericRepository<Course>menjadiCourseRepository:

private CourseRepository courseRepository;
public CourseRepository CourseRepository
{
    get
    {

        if (this.courseRepository == null)
        {
            this.courseRepository = new CourseRepository(context);
        }
        return courseRepository;
    }
}

Di CourseController.cs, tambahkan UpdateCourseCredits metode:

public ActionResult UpdateCourseCredits(int? multiplier)
{
    if (multiplier != null)
    {
        ViewBag.RowsAffected = unitOfWork.CourseRepository.UpdateCourseCredits(multiplier.Value);
    }
    return View();
}

Metode ini akan digunakan untuk dan HttpGet HttpPost. HttpGet UpdateCourseCredits Ketika metode berjalan, multiplier variabel akan null dan tampilan akan menampilkan kotak teks kosong dan tombol kirim, seperti yang ditunjukkan pada ilustrasi sebelumnya.

Ketika tombol Perbarui diklik dan HttpPost metode berjalan, multiplier akan memiliki nilai yang dimasukkan dalam kotak teks. Kode kemudian memanggil metode repositori UpdateCourseCredits , yang mengembalikan jumlah baris yang terpengaruh, dan nilai tersebut disimpan dalam ViewBag objek. Saat tampilan menerima jumlah baris yang terpengaruh dalam objek, tampilan nomor tersebut ViewBag bukan kotak teks dan tombol kirim, seperti yang ditunjukkan dalam ilustrasi berikut:

Cuplikan layar yang memperlihatkan halaman yang terpengaruh baris Kredit Kursus Pembaruan Universitas Contoso.

Buat tampilan di folder Views\Course untuk halaman Perbarui Kredit Kursus:

Cuplikan layar yang memperlihatkan kotak dialog Tambahkan Tampilan. Perbarui Kredit Kursus dimasukkan di bidang Teks nama tampilan.

Di Views\Course\UpdateCourseCredits.cshtml, ganti kode templat dengan kode berikut:

@model ContosoUniversity.Models.Course

@{
    ViewBag.Title = "UpdateCourseCredits";
}

<h2>Update Course Credits</h2>

@if (ViewBag.RowsAffected == null)
{
    using (Html.BeginForm())
    {
        <p>
            Enter a number to multiply every course's credits by: @Html.TextBox("multiplier")
        </p>
        <p>
            <input type="submit" value="Update" />
        </p>
    }
}
@if (ViewBag.RowsAffected != null)
{
    <p>
        Number of rows updated: @ViewBag.RowsAffected
    </p>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

UpdateCourseCredits Jalankan metode dengan memilih tab Kursus, lalu tambahkan "/UpdateCourseCredits" ke akhir URL di bilah alamat browser (misalnya: http://localhost:50205/Course/UpdateCourseCredits). Masukkan angka dalam kotak teks:

Cuplikan layar memperlihatkan halaman awal Perbarui Kredit Kursus dengan angka 2 dimasukkan di bidang teks.

Klik Perbarui. Anda melihat jumlah baris yang terpengaruh:

Cuplikan layar yang memperlihatkan halaman Perbarui Kredit Kursus dengan jumlah baris yang diperbarui.

Klik Kembali ke Daftar untuk melihat daftar kursus dengan jumlah kredit yang direvisi.

Cuplikan layar yang memperlihatkan halaman Indeks Kursus. Daftar kursus ditampilkan dengan jumlah kredit yang direvisi.

Untuk informasi selengkapnya tentang kueri SQL mentah, lihat Kueri SQL Mentah di blog tim Kerangka Kerja Entitas.

Kueri Tanpa Pelacakan

Saat konteks database mengambil baris database dan membuat objek entitas yang mewakilinya, secara default konteks tersebut melacak apakah entitas dalam memori sinkron dengan apa yang ada di database. Data dalam memori bertindak sebagai cache dan digunakan saat Anda memperbarui entitas. Penembolokan ini sering kali tidak perlu dalam aplikasi web karena instans konteks biasanya berumur pendek (yang baru dibuat dan dibuang untuk setiap permintaan) dan konteks yang membaca entitas biasanya dibuang sebelum entitas tersebut digunakan lagi.

Anda dapat menentukan apakah konteks melacak objek entitas untuk kueri dengan menggunakan metode .AsNoTracking Skenario umum di mana Anda mungkin ingin melakukannya termasuk yang berikut ini:

  • Kueri mengambil data dalam volume besar yang menonaktifkan pelacakan mungkin terlihat meningkatkan performa.
  • Anda ingin melampirkan entitas untuk memperbaruinya, tetapi Anda sebelumnya mengambil entitas yang sama untuk tujuan yang berbeda. Karena entitas sudah dilacak oleh konteks database, Anda tidak dapat melampirkan entitas yang ingin Anda ubah. Salah satu cara untuk mencegah hal ini terjadi adalah dengan menggunakan AsNoTracking opsi dengan kueri sebelumnya.

Di bagian ini Anda akan menerapkan logika bisnis yang mengilustrasikan yang kedua dari skenario ini. Secara khusus, Anda akan menerapkan aturan bisnis yang mengatakan bahwa instruktur tidak dapat menjadi administrator lebih dari satu departemen.

Dalam DepartmentController.cs, tambahkan metode baru yang dapat Anda panggil dari Edit metode dan Create untuk memastikan bahwa tidak ada dua departemen yang memiliki administrator yang sama:

private void ValidateOneAdministratorAssignmentPerInstructor(Department department)
{
    if (department.PersonID != null)
    {
        var duplicateDepartment = db.Departments
            .Include("Administrator")
            .Where(d => d.PersonID == department.PersonID)
            .FirstOrDefault();
        if (duplicateDepartment != null && duplicateDepartment.DepartmentID != department.DepartmentID)
        {
            var errorMessage = String.Format(
                "Instructor {0} {1} is already administrator of the {2} department.",
                duplicateDepartment.Administrator.FirstMidName,
                duplicateDepartment.Administrator.LastName,
                duplicateDepartment.Name);
            ModelState.AddModelError(string.Empty, errorMessage);
        }
    }
}

Tambahkan kode di try blok HttpPost Edit metode untuk memanggil metode baru ini jika tidak ada kesalahan validasi. try Blok sekarang terlihat seperti contoh berikut:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(
   [Bind(Include = "DepartmentID, Name, Budget, StartDate, RowVersion, PersonID")]
    Department department)
{
   try
   {
      if (ModelState.IsValid)
      {
         ValidateOneAdministratorAssignmentPerInstructor(department);
      }

      if (ModelState.IsValid)
      {
         db.Entry(department).State = EntityState.Modified;
         db.SaveChanges();
         return RedirectToAction("Index");
      }
   }
   catch (DbUpdateConcurrencyException ex)
   {
      var entry = ex.Entries.Single();
      var clientValues = (Department)entry.Entity;

Jalankan halaman Edit Departemen dan coba ubah administrator departemen menjadi instruktur yang sudah menjadi administrator departemen yang berbeda. Anda mendapatkan pesan kesalahan yang diharapkan:

Cuplikan layar memperlihatkan halaman Edit Departemen dengan pesan kesalahan administrator duplikat.

Sekarang jalankan halaman Edit Departemen lagi dan kali ini ubah jumlah Anggaran . Saat Anda mengklik Simpan, Anda akan melihat halaman kesalahan:

Cuplikan layar yang memperlihatkan halaman Edit Departemen dengan pesan kesalahan manajer status objek.

Pesan kesalahan pengecualian adalah "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key." Ini terjadi karena urutan peristiwa berikut:

  • Metode ini Edit memanggil ValidateOneAdministratorAssignmentPerInstructor metode , yang mengambil semua departemen yang memiliki Kim Abercrombie sebagai administrator mereka. Itu menyebabkan departemen Inggris dibaca. Karena itu adalah departemen yang sedang diedit, tidak ada kesalahan yang dilaporkan. Namun, sebagai hasil dari operasi baca ini, entitas departemen Bahasa Inggris yang dibaca dari database sekarang sedang dilacak oleh konteks database.
  • Metode ini Edit mencoba mengatur Modified bendera pada entitas departemen Bahasa Inggris yang dibuat oleh pengikat model MVC, tetapi itu gagal karena konteks sudah melacak entitas untuk departemen bahasa Inggris.

Salah satu solusi untuk masalah ini adalah menjaga konteks dari pelacakan entitas departemen dalam memori yang diambil oleh kueri validasi. Tidak ada kerugian untuk melakukan ini, karena Anda tidak akan memperbarui entitas ini atau membacanya lagi dengan cara yang akan mendapat manfaat darinya di-cache dalam memori.

Dalam DepartmentController.cs, dalam ValidateOneAdministratorAssignmentPerInstructor metode , tentukan tidak ada pelacakan, seperti yang ditunjukkan dalam hal berikut:

var duplicateDepartment = db.Departments
   .Include("Administrator")
   .Where(d => d.PersonID == department.PersonID)
   .AsNoTracking()
   .FirstOrDefault();

Ulangi upaya Anda untuk mengedit jumlah Anggaran departemen. Kali ini operasi berhasil, dan situs kembali seperti yang diharapkan ke halaman Indeks Departemen, memperlihatkan nilai anggaran yang direvisi.

Memeriksa Kueri yang Dikirim ke Database

Terkadang sangat membantu untuk dapat melihat kueri SQL aktual yang dikirim ke database. Untuk melakukan ini, Anda dapat memeriksa variabel kueri di debugger atau memanggil metode kueri ToString . Untuk mencobanya, Anda akan melihat kueri sederhana lalu melihat apa yang terjadi saat Anda menambahkan opsi seperti memuat, memfilter, dan mengurutkan yang bersemangat.

Di Pengontrol/CourseController, ganti Index metode dengan kode berikut:

public ViewResult Index()
{
    var courses = unitOfWork.CourseRepository.Get();
    return View(courses.ToList());
}

Sekarang atur titik henti di GenericRepository.cs pada return query.ToList(); return orderBy(query).ToList(); dan pernyataan Get metode . Jalankan proyek dalam mode debug dan pilih halaman Indeks Kursus. Ketika kode mencapai titik henti, periksa query variabel . Anda melihat kueri yang dikirim ke SQL Server. Ini adalah pernyataan sederhana Select :

{SELECT 
[Extent1].[CourseID] AS [CourseID], 
[Extent1].[Title] AS [Title], 
[Extent1].[Credits] AS [Credits], 
[Extent1].[DepartmentID] AS [DepartmentID]
FROM [Course] AS [Extent1]}

Cuplikan layar yang memperlihatkan contoh aplikasi web tab Repositori Generik. Variabel kueri dipilih.

Kueri bisa terlalu panjang untuk ditampilkan di jendela penelusuran kesalahan di Visual Studio. Untuk melihat seluruh kueri, Anda bisa menyalin nilai variabel dan menempelkannya ke editor teks:

Cuplikan layar yang memperlihatkan nilai variabel dengan menu dropdown yang ditampilkan saat dipilih. Opsi Salin Nilai disorot.

Sekarang Anda akan menambahkan daftar drop-down ke halaman Indeks Kursus sehingga pengguna dapat memfilter departemen tertentu. Anda akan mengurutkan kursus berdasarkan judul, dan Anda akan menentukan pemuatan yang bersemangat untuk Department properti navigasi. Di CourseController.cs, ganti Index metode dengan kode berikut:

public ActionResult Index(int? SelectedDepartment)
{
    var departments = unitOfWork.DepartmentRepository.Get(
        orderBy: q => q.OrderBy(d => d.Name));
    ViewBag.SelectedDepartment = new SelectList(departments, "DepartmentID", "Name", SelectedDepartment);

    int departmentID = SelectedDepartment.GetValueOrDefault(); 
    return View(unitOfWork.CourseRepository.Get(
        filter: d => !SelectedDepartment.HasValue || d.DepartmentID == departmentID,
        orderBy: q => q.OrderBy(d => d.CourseID),
        includeProperties: "Department"));
}

Metode ini menerima nilai yang dipilih dari daftar drop-down dalam SelectedDepartment parameter . Jika tidak ada yang dipilih, parameter ini akan null.

Koleksi SelectList yang berisi semua departemen diteruskan ke tampilan untuk daftar drop-down. Parameter yang diteruskan ke SelectList konstruktor menentukan nama bidang nilai, nama bidang teks, dan item yang dipilih.

Get Untuk metode Course repositori, kode menentukan ekspresi filter, urutan pengurutan, dan pemuatan bersemangat untuk Department properti navigasi. Ekspresi filter selalu mengembalikan true jika tidak ada yang dipilih di daftar drop-down (artinya, SelectedDepartment null).

Di Views\Course\Index.cshtml, segera sebelum tag pembuka table , tambahkan kode berikut untuk membuat daftar drop-down dan tombol kirim:

@using (Html.BeginForm())
{
    <p>Select Department: @Html.DropDownList("SelectedDepartment","All")   
    <input type="submit" value="Filter" /></p>
}

Dengan titik henti yang masih diatur di GenericRepository kelas, jalankan halaman Indeks Kursus. Lanjutkan melalui dua kali pertama bahwa kode mencapai titik henti, sehingga halaman ditampilkan di browser. Pilih departemen dari daftar drop-down dan klik Filter:

Cuplikan layar yang memperlihatkan halaman Indeks Kursus dengan Departemen Ekonomi dipilih.

Kali ini titik henti pertama adalah untuk kueri departemen untuk daftar drop-down. Lewati itu dan lihat query variabel saat berikutnya kode mencapai titik henti untuk melihat seperti apa Course kueri sekarang. Anda akan melihat sesuatu seperti berikut ini:

{SELECT 
[Extent1].[CourseID] AS [CourseID], 
[Extent1].[Title] AS [Title], 
[Extent1].[Credits] AS [Credits], 
[Extent1].[DepartmentID] AS [DepartmentID], 
[Extent2].[DepartmentID] AS [DepartmentID1], 
[Extent2].[Name] AS [Name], 
[Extent2].[Budget] AS [Budget], 
[Extent2].[StartDate] AS [StartDate], 
[Extent2].[PersonID] AS [PersonID], 
[Extent2].[Timestamp] AS [Timestamp]
FROM  [Course] AS [Extent1]
INNER JOIN [Department] AS [Extent2] ON [Extent1].[DepartmentID] = [Extent2].[DepartmentID]
WHERE (@p__linq__0 IS NULL) OR ([Extent1].[DepartmentID] = @p__linq__1)}

Anda bisa melihat bahwa kueri sekarang menjadi JOIN kueri yang memuat Department data bersama dengan Course data, dan menyertakan WHERE klausa.

Bekerja dengan Kelas Proksi

Ketika Kerangka Kerja Entitas membuat instans entitas (misalnya, saat Anda menjalankan kueri), kerangka kerja tersebut sering membuatnya sebagai instans jenis turunan yang dihasilkan secara dinamis yang bertindak sebagai proksi untuk entitas. Proksi ini mengambil alih beberapa properti virtual entitas untuk menyisipkan kait untuk melakukan tindakan secara otomatis saat properti diakses. Misalnya, mekanisme ini digunakan untuk mendukung pemuatan hubungan yang malas.

Sebagian besar waktu Anda tidak perlu menyadari penggunaan proksi ini, tetapi ada pengecualian:

  • Dalam beberapa skenario, Anda mungkin ingin mencegah Kerangka Kerja Entitas membuat instans proksi. Misalnya, menserialisasikan instans non-proksi mungkin lebih efisien daripada menserialisasikan instans proksi.
  • Saat membuat instans kelas entitas menggunakan new operator, Anda tidak mendapatkan instans proksi. Ini berarti Anda tidak mendapatkan fungsionalitas seperti pemuatan malas dan pelacakan perubahan otomatis. Ini biasanya baik-baik saja; Anda umumnya tidak memerlukan pemuatan malas, karena Anda membuat entitas baru yang tidak ada dalam database, dan Anda umumnya tidak memerlukan pelacakan perubahan jika Anda secara eksplisit menandai entitas sebagai Added. Namun, jika Anda membutuhkan pemuatan malas dan Anda memerlukan pelacakan perubahan, Anda dapat membuat instans entitas baru dengan proksi menggunakan Create metode DbSet kelas .
  • Anda mungkin ingin mendapatkan jenis entitas aktual dari jenis proksi. Anda dapat menggunakan GetObjectType metode ObjectContext kelas untuk mendapatkan jenis entitas aktual dari instans jenis proksi.

Untuk informasi selengkapnya, lihat Bekerja dengan Proksi di blog tim Kerangka Kerja Entitas.

Menonaktifkan Deteksi Perubahan Otomatis

Kerangka Kerja Entitas menentukan bagaimana entitas telah berubah (dan oleh karena itu pembaruan mana yang perlu dikirim ke database) dengan membandingkan nilai entitas saat ini dengan nilai asli. Nilai asli disimpan saat entitas dikueri atau dilampirkan. Beberapa metode yang menyebabkan deteksi perubahan otomatis adalah sebagai berikut:

  • DbSet.Find
  • DbSet.Local
  • DbSet.Remove
  • DbSet.Add
  • DbSet.Attach
  • DbContext.SaveChanges
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries

Jika Anda melacak sejumlah besar entitas dan memanggil salah satu metode ini berkali-kali dalam perulangan, Anda mungkin mendapatkan peningkatan performa yang signifikan dengan menonaktifkan deteksi perubahan otomatis untuk sementara menggunakan properti AutoDetectChangesEnabled . Untuk informasi selengkapnya, lihat Mendeteksi Perubahan secara otomatis.

Menonaktifkan Validasi Saat Menyimpan Perubahan

Saat Anda memanggil metode , SaveChanges secara default Kerangka Kerja Entitas memvalidasi data di semua properti semua entitas yang diubah sebelum memperbarui database. Jika Anda telah memperbarui sejumlah besar entitas dan Anda telah memvalidasi data, pekerjaan ini tidak perlu dan Anda dapat membuat proses menyimpan perubahan membutuhkan waktu lebih sedikit dengan menonaktifkan validasi untuk sementara waktu. Anda dapat melakukannya menggunakan properti ValidateOnSaveEnabled . Untuk informasi selengkapnya, lihat Validasi.

Ringkasan

Ini menyelesaikan rangkaian tutorial ini tentang menggunakan Kerangka Kerja Entitas dalam aplikasi MVC ASP.NET. Tautan ke sumber daya Entity Framework lainnya dapat ditemukan di Peta Konten Akses Data ASP.NET.

Untuk informasi selengkapnya tentang cara menyebarkan aplikasi web setelah Anda membuatnya, lihat ASP.NET Peta Konten Penyebaran di Pustaka MSDN.

Untuk informasi tentang topik lain yang terkait dengan MVC, seperti autentikasi dan otorisasi, lihat Sumber Daya yang Direkomendasikan MVC.

Ucapan terima kasih

  • Tom Dykstra menulis versi asli tutorial ini dan merupakan penulis pemrograman senior di Microsoft Web Platform and Tools Content Team.
  • Rick Anderson (twitter @RickAndMSFT) menulis bersama tutorial ini dan melakukan sebagian besar pekerjaan memperbaruinya untuk EF 5 dan MVC 4. Rick adalah penulis pemrograman senior untuk Microsoft yang berfokus pada Azure dan MVC.
  • Rowan Miller dan anggota tim Entity Framework lainnya membantu tinjauan kode dan membantu men-debug banyak masalah dengan migrasi yang muncul saat kami memperbarui tutorial untuk EF 5.

VB

Ketika tutorial awalnya diproduksi, kami menyediakan versi C# dan VB dari proyek unduhan yang telah selesai. Dengan pembaruan ini, kami menyediakan proyek yang dapat diunduh C# untuk setiap bab untuk mempermudah memulai di mana saja dalam seri, tetapi karena keterbatasan waktu dan prioritas lain, kami tidak melakukannya untuk VB. Jika Anda membangun proyek VB menggunakan tutorial ini dan bersedia untuk membagikannya dengan orang lain, beri tahu kami.

Kesalahan dan Solusi

Tidak dapat membuat/menyalin bayangan

Pesan Kesalahan:

Tidak dapat membuat/menyalin bayangan 'DotNetOpenAuth.OpenId' ketika file tersebut sudah ada.

Solusi:

Tunggu beberapa detik dan refresh halaman.

Update-Database tidak dikenali

Pesan Kesalahan:

Istilah 'Update-Database' tidak dikenali sebagai nama cmdlet, fungsi, file skrip, atau program yang dapat dioperasikan. Periksa ejaan nama, atau jika jalur disertakan, verifikasi bahwa jalur tersebut benar dan coba lagi.(Dari Update-Database perintah di PMC.)

Solusi:

Keluar dari Visual Studio. Buka kembali proyek dan coba lagi.

Validasi gagal

Pesan Kesalahan:

Validasi gagal untuk satu atau beberapa entitas. Lihat properti 'EntityValidationErrors' untuk detail selengkapnya. (Dari Update-Database perintah di PMC.)

Solusi:

Salah satu penyebab masalah ini adalah kesalahan validasi ketika Seed metode berjalan. Lihat Seeding dan Debugging Entity Framework (EF) DB untuk tips tentang penelusuran kesalahan Seed metode.

Kesalahan HTTP 500.19

Pesan Kesalahan:

Kesalahan HTTP 500.19 - Kesalahan Server Internal
Halaman yang diminta tidak dapat diakses karena data konfigurasi terkait untuk halaman tidak valid.

Solusi:

Salah satu cara Anda bisa mendapatkan kesalahan ini adalah dari memiliki beberapa salinan solusi, masing-masing menggunakan nomor port yang sama. Anda biasanya dapat menyelesaikan masalah ini dengan keluar dari semua instans Visual Studio, lalu memulai ulang proyek yang sedang Anda kerjakan. Jika tidak berhasil, coba ubah nomor port. Klik kanan pada file proyek lalu klik properti. Pilih tab Web lalu ubah nomor port di kotak teks Url Proyek.

Kesalahan menemukan instans SQL Server

Pesan Kesalahan:

Timbul kesalahan terkait jaringan atau spesifik instans saat membuat sambungan ke SQL Server. Server tak ditemukan atau tak bisa diakses. Verifikasi bahwa nama instans sudah benar dan SQL Server dikonfigurasi untuk memungkinkan koneksi jarak jauh. (penyedia: Antarmuka Jaringan SQL Server, kesalahan: 26 - Kesalahan Menemukan Server/instans yang ditentukan)

Solusi:

Periksa string koneksi. Jika Anda telah menghapus database secara manual, ubah nama database dalam string konstruksi.