Kerangka Kerja Entitas - Panduan Cepat

Apa itu Entity Framework?

Entity Framework pertama kali dirilis pada tahun 2008, alat utama Microsoft untuk berinteraksi antara aplikasi .NET dan database relasional. Entity Framework adalah Object Relational Mapper (ORM) yang merupakan jenis alat yang menyederhanakan pemetaan antara objek di perangkat lunak Anda ke tabel dan kolom database relasional.

  • Entity Framework (EF) adalah framework ORM open source untuk ADO.NET yang merupakan bagian dari .NET Framework.

  • ORM menangani pembuatan koneksi database dan menjalankan perintah, serta mengambil hasil kueri dan secara otomatis mewujudkan hasil tersebut sebagai objek aplikasi Anda.

  • ORM juga membantu melacak perubahan pada objek tersebut, dan ketika diinstruksikan, ORM juga akan mempertahankan perubahan tersebut kembali ke database untuk Anda.

Mengapa Entity Framework?

Entity Framework adalah ORM dan ORM bertujuan untuk meningkatkan produktivitas pengembang dengan mengurangi tugas yang berlebihan dalam mempertahankan data yang digunakan dalam aplikasi.

  • Entity Framework dapat menghasilkan perintah database yang diperlukan untuk membaca atau menulis data dalam database dan menjalankannya untuk Anda.

  • Jika Anda membuat kueri, Anda dapat mengekspresikan kueri Anda terhadap objek domain Anda menggunakan LINQ ke entitas.

  • Kerangka Kerja Entitas akan mengeksekusi kueri yang relevan dalam database dan kemudian mewujudkan hasilnya menjadi contoh objek domain Anda untuk Anda kerjakan dalam aplikasi Anda.

Ada ORM lain di pasar seperti NHibernate dan LLBLGen Pro. Kebanyakan ORM biasanya memetakan tipe domain langsung ke skema database.

Kerangka Kerja Entitas memiliki lapisan pemetaan yang lebih terperinci sehingga Anda dapat menyesuaikan pemetaan, misalnya, dengan memetakan satu entitas ke beberapa tabel database atau bahkan beberapa entitas ke satu tabel.

  • Entity Framework adalah teknologi akses data yang direkomendasikan Microsoft untuk aplikasi baru.

  • ADO.NET tampaknya merujuk langsung ke teknologi untuk kumpulan data dan tabel data.

  • Kerangka Kerja Entitas adalah tempat semua investasi bergerak maju dilakukan, yang telah terjadi selama beberapa tahun.

  • Microsoft menganjurkan agar Anda menggunakan Entity Framework melalui ADO.NET atau LINQ ke SQL untuk semua pengembangan baru.

Model konseptual

Untuk pengembang yang terbiasa dengan pengembangan yang berfokus pada basis data, perubahan terbesar dengan Kerangka Kerja Entitas adalah memungkinkan Anda fokus pada domain bisnis Anda. Apa yang Anda ingin aplikasi Anda lakukan tanpa dibatasi oleh kemampuan database?

  • Dengan Entity Framework, titik fokus disebut sebagai model konseptual. Ini adalah model objek dalam aplikasi Anda, bukan model database yang Anda gunakan untuk mempertahankan data aplikasi Anda.

  • Model konseptual Anda mungkin kebetulan sejalan dengan skema database Anda atau mungkin sangat berbeda.

  • Anda dapat menggunakan Perancang Visual untuk menentukan model konseptual Anda, yang kemudian dapat menghasilkan kelas yang pada akhirnya akan Anda gunakan dalam aplikasi Anda.

  • Anda bisa menentukan kelas Anda dan menggunakan fitur Entity Framework yang disebut Code First. Dan kemudian Entity Framework akan memahami model konseptual.

Entitas Framework mencari cara untuk berpindah dari model konseptual ke database Anda. Jadi, Anda bisa membuat kueri terhadap objek model konseptual Anda dan bekerja langsung dengannya.

fitur

Berikut adalah fitur dasar Entity Framework. Daftar ini dibuat berdasarkan fitur yang paling terkenal dan juga dari pertanyaan umum tentang Entity Framework.

  • Entity Framework adalah alat Microsoft.
  • Kerangka Kerja Entitas sedang dikembangkan sebagai produk Sumber Terbuka.
  • Entity Framework tidak lagi terikat atau bergantung pada siklus rilis .NET.
  • Bekerja dengan database relasional apa pun dengan penyedia Entity Framework yang valid.
  • Pembuatan perintah SQL dari LINQ ke Entitas.
  • Entity Framework akan membuat kueri berparameter.
  • Melacak perubahan pada objek dalam memori.
  • Memungkinkan untuk memasukkan, memperbarui dan menghapus pembuatan perintah.
  • Bekerja dengan model visual atau dengan kelas Anda sendiri.
  • Kerangka Kerja Entitas telah menyimpan Dukungan Prosedur.

Arsitektur Entity Framework, dari bawah ke atas, terdiri dari:

Penyedia Data

Ini adalah penyedia khusus sumber, yang mengabstraksikan antarmuka ADO.NET untuk menyambung ke database saat pemrograman melawan skema konseptual.

Ini menerjemahkan bahasa SQL umum seperti LINQ melalui pohon perintah ke ekspresi SQL asli dan mengeksekusinya terhadap sistem DBMS tertentu.

Klien Entitas

Lapisan ini memaparkan lapisan entitas ke lapisan atas. Klien entitas memberikan kemampuan bagi pengembang untuk bekerja melawan entitas dalam bentuk baris dan kolom menggunakan kueri SQL entitas tanpa perlu membuat kelas untuk mewakili skema konseptual. Entity Client menunjukkan lapisan kerangka entitas, yang merupakan fungsionalitas inti. Lapisan ini disebut sebagai Model Data Entitas.

  • Itu Storage Layer berisi seluruh skema database dalam format XML.

  • Itu Entity Layer yang juga merupakan file XML yang mendefinisikan entitas dan hubungan.

  • Itu Mapping layer adalah file XML yang memetakan entitas dan hubungan yang ditentukan pada lapisan konseptual dengan hubungan aktual dan tabel yang ditentukan pada lapisan logis.

  • Itu Metadata services yang juga diwakili dalam Entitas, Klien menyediakan API terpusat untuk mengakses metadata yang tersimpan di lapisan Entitas, Pemetaan, dan Penyimpanan.

Layanan Objek

Lapisan Object Services adalah Konteks Objek, yang mewakili sesi interaksi antara aplikasi dan sumber data.

  • Penggunaan utama dari Konteks Objek adalah untuk melakukan operasi yang berbeda seperti menambah, menghapus contoh entitas dan untuk menyimpan kembali keadaan yang diubah ke database dengan bantuan kueri.

  • Ini adalah lapisan ORM dari Entity Framework, yang mewakili hasil data ke instance objek entitas.

  • Layanan ini memungkinkan pengembang untuk menggunakan beberapa fitur ORM yang kaya seperti pemetaan kunci utama, pelacakan perubahan, dll. Dengan menulis kueri menggunakan LINQ dan Entity SQL.

Apa yang Baru di Entity Framework 6?

Framework memiliki API kompleks yang memungkinkan Anda memiliki kontrol terperinci atas segala hal mulai dari pemodelan hingga perilaku runtime-nya. Bagian dari Entity Framework 5 berada di dalam .NET. Dan bagian lainnya berada di dalam rakitan tambahan yang didistribusikan menggunakan NuGet.

  • Fungsionalitas inti Entity Framework dibangun ke dalam .NET Framework.

  • Dukungan Code First, itulah yang memungkinkan Entity Framework menggunakan kelas sebagai pengganti model visual, dan API yang lebih ringan untuk berinteraksi dengan EF ada dalam paket NuGet.

  • Intinya adalah apa yang menyediakan kueri, pelacakan perubahan, dan semua transformasi dari kueri Anda ke kueri SQL serta dari data yang dikembalikan ke objek.

  • Anda dapat menggunakan paket EF 5 NuGet dengan .NET 4 dan dengan .NET 4.5.

  • Satu hal besar yang membingungkan - .NET 4.5 menambahkan dukungan untuk enum dan data spasial ke API Kerangka Kerja Entitas inti, yang berarti jika Anda menggunakan EF 5 dengan .NET 4, Anda tidak akan mendapatkan fitur baru ini. Anda hanya akan mendapatkannya saat menggabungkan EF5 dengan .NET 4.5.

Sekarang mari kita lihat Entity Framework 6. Inti API yang ada di dalam .NET di Entity Framework 6 sekarang menjadi bagian dari paket NuGet.

Artinya -

  • Semua Kerangka Entitas berada di dalam rakitan yang didistribusikan oleh NuGet ini

  • Anda tidak akan bergantung pada .NET untuk menyediakan fitur khusus seperti dukungan enum Entity Framework dan dukungan data khusus.

  • Anda akan melihat bahwa salah satu fitur EF6 adalah mendukung enum dan data spasial untuk .NET 4

Untuk mulai mengerjakan Entity Framework Anda perlu menginstal alat pengembangan berikut -

  • Visual Studio 2013 atau yang lebih baru
  • SQL Server 2012 atau yang lebih baru
  • Pembaruan Entity Framework dari NuGet Package

Microsoft menyediakan visual studio versi gratis yang juga berisi SQL Server dan dapat diunduh dari www.visualstudio.com .

Instalasi

Step 1- Setelah pengunduhan selesai, jalankan penginstal. Dialog berikut akan ditampilkan.

Step 2 - Klik pada tombol Install dan itu akan memulai proses instalasi.

Step 3- Setelah proses instalasi selesai dengan sukses, Anda akan melihat dialog berikut. Tutup dialog ini dan mulai ulang komputer Anda jika diperlukan.

Step 4- Buka Visual Studio dari Start Menu yang akan membuka dialog berikut. Ini akan menjadi sementara untuk pertama kalinya untuk persiapan.

Step 5 - Setelah semuanya selesai, Anda akan melihat jendela utama Visual studio.

Mari buat proyek baru dari File → New → Project

Step 1 - Pilih Aplikasi Konsol dan klik tombol OK.

Step 2 - Di Solution Explorer, klik kanan pada proyek Anda.

Step 3 - Pilih Kelola Paket NuGet seperti yang ditunjukkan pada gambar di atas, yang akan membuka jendela berikut di Visual Studio.

Step 4 - Cari Entity Framework dan instal versi terbaru dengan menekan tombol instal.

Step 5- Klik Ok. Setelah instalasi selesai, Anda akan melihat pesan berikut di jendela keluaran Anda.

Anda sekarang siap untuk memulai aplikasi Anda.

Dalam tutorial ini, kita akan menggunakan database Universitas sederhana. Database Universitas bisa jauh lebih kompleks secara keseluruhan tetapi untuk tujuan demo dan pembelajaran, kami menggunakan bentuk paling sederhana dari database ini. Diagram berikut berisi tiga tabel.

  • Student
  • Course
  • Enrollment

Kapanpun istilah database digunakan, satu hal muncul langsung di benak kita dan itu adalah jenis tabel yang berbeda yang memiliki semacam hubungan. Ada tiga tipe hubungan antar tabel dan hubungan antara tabel berbeda bergantung pada bagaimana kolom terkait ditentukan.

  • Hubungan Satu-ke-Banyak
  • Hubungan Banyak ke Banyak
  • Hubungan Satu-ke-Satu

Hubungan Satu-ke-Banyak

Hubungan satu ke banyak adalah jenis hubungan yang paling umum. Dalam jenis hubungan ini, baris dalam tabel A dapat memiliki banyak baris yang cocok dalam tabel B, tetapi baris dalam tabel B hanya dapat memiliki satu baris yang cocok dalam tabel A.Misalnya, pada diagram di atas, tabel Siswa dan Pendaftaran memiliki satu baris Hubungan-ke-banyak, setiap siswa mungkin memiliki banyak pendaftaran, tetapi setiap pendaftaran hanya dimiliki oleh satu siswa.

Hubungan Banyak ke Banyak

Dalam hubungan banyak-ke-banyak, baris dalam tabel A dapat memiliki banyak baris yang cocok dalam tabel B, dan sebaliknya. Anda membuat hubungan seperti itu dengan menentukan tabel ketiga, yang disebut tabel junction, yang kunci utamanya terdiri dari kunci asing dari tabel A dan tabel B. Misalnya, tabel Siswa dan Kursus memiliki hubungan banyak-ke-banyak yang ditentukan oleh hubungan satu-ke-banyak dari masing-masing tabel ini ke tabel Pendaftaran.

Hubungan Satu-ke-Satu

Dalam hubungan satu-ke-satu, baris dalam tabel A tidak dapat memiliki lebih dari satu baris yang cocok dalam tabel B, dan sebaliknya. Hubungan satu-ke-satu dibuat jika kedua kolom terkait adalah kunci utama atau memiliki batasan unik.

Jenis hubungan ini tidak umum karena sebagian besar informasi yang terkait dengan cara ini akan menjadi tabel all-in-one. Anda dapat menggunakan hubungan satu-ke-satu untuk -

  • Bagilah tabel dengan banyak kolom.
  • Pisahkan bagian dari tabel untuk alasan keamanan.
  • Menyimpan data yang berumur pendek dan dapat dengan mudah dihapus hanya dengan menghapus tabel.
  • Simpan informasi yang hanya berlaku untuk subset dari tabel utama.

Entity Data Model (EDM) adalah versi perluasan dari model Entity-Relationship yang menentukan model konseptual data menggunakan berbagai teknik pemodelan. Ini juga mengacu pada sekumpulan konsep yang menggambarkan struktur data, terlepas dari bentuk yang disimpan.

EDM mendukung sekumpulan tipe data primitif yang mendefinisikan properti dalam model konseptual. Kita perlu mempertimbangkan 3 bagian inti yang menjadi dasar dari Kerangka Kerja Entitas dan secara kolektif dikenal sebagai Model Data Entitas. Berikut adalah tiga bagian inti EDM.

  • Model Skema Penyimpanan
  • Model Konseptual
  • Model Pemetaan

Model Skema Penyimpanan

Model Penyimpanan juga disebut sebagai Storage Schema Definition Layer (SSDL) mewakili representasi skematis dari penyimpanan data backend.

Model Konseptual

Model Konseptual juga disebut sebagai Lapisan Definisi Skema Konseptual (CSDL) adalah model entitas nyata, yang digunakan untuk menulis kueri kami.

Model Pemetaan

Mapping Layer hanyalah pemetaan antara model Konseptual dan model Storage.

Skema logis dan pemetaannya dengan skema fisik direpresentasikan sebagai EDM.

  • Visual Studio juga menyediakan Entity Designer, untuk pembuatan visual EDM dan spesifikasi pemetaan.

  • Keluaran alat ini adalah file XML (* .edmx) yang menentukan skema dan pemetaan.

  • File Edmx berisi artefak metadata Entity Framework.

Bahasa Definisi Skema

Kerangka kerja entitas ADO.NET menggunakan bahasa definisi data berbasis XML yang disebut bahasa definisi skema (SDL) untuk menentukan skema EDM.

  • SDL mendefinisikan Tipe Sederhana yang mirip dengan tipe primitif lainnya, termasuk String, Int32, Double, Decimal, dan DateTime, dan lainnya.

  • Enumerasi, yang mendefinisikan peta nilai dan nama primitif, juga dianggap sebagai tipe sederhana.

  • Pencacahan hanya didukung dari kerangka kerja versi 5.0 dan seterusnya.

  • Jenis Kompleks dibuat dari agregasi jenis lain. Kumpulan properti dari tipe ini menentukan Tipe Entitas.

Model data utamanya memiliki tiga konsep utama untuk mendeskripsikan struktur data -

  • Jenis entitas
  • Jenis asosiasi
  • Property

Jenis Entitas

Jenis entitas adalah blok bangunan fundamental untuk menggambarkan struktur data di EDM.

  • Dalam model konseptual, jenis entitas dibangun dari properti dan menggambarkan struktur konsep tingkat atas, seperti Siswa dan Pendaftaran dalam aplikasi bisnis.

  • Entitas mewakili objek tertentu seperti Siswa atau Pendaftaran tertentu.

  • Setiap entitas harus memiliki kunci entitas unik dalam kumpulan entitas. Kumpulan entitas adalah kumpulan contoh dari tipe entitas tertentu. Kumpulan entitas (dan kumpulan asosiasi) secara logis dikelompokkan dalam wadah entitas.

  • Warisan didukung dengan jenis entitas, yaitu satu jenis entitas dapat diturunkan dari yang lain.

Jenis Asosiasi

Ini adalah blok bangunan fundamental lain untuk menggambarkan hubungan di EDM. Dalam model konseptual, sebuah asosiasi merepresentasikan hubungan antara dua tipe entitas seperti Student dan Enrollment.

  • Setiap pengaitan memiliki dua ujung pengaitan yang menentukan jenis entitas yang terlibat dalam pengaitan.

  • Setiap ujung asosiasi juga menetapkan multiplisitas ujung asosiasi yang menunjukkan jumlah entitas yang dapat berada di ujung asosiasi tersebut.

  • Multiplisitas ujung asosiasi dapat memiliki nilai satu (1), nol atau satu (0..1), atau banyak (*).

  • Entitas di salah satu ujung asosiasi dapat diakses melalui properti navigasi, atau melalui kunci asing jika diekspos pada tipe entitas.

Properti

Jenis entitas berisi properti yang menentukan struktur dan karakteristiknya. Misalnya, tipe entitas Mahasiswa mungkin memiliki properti seperti Id Mahasiswa, Nama, dll.

Properti dapat berisi data primitif (seperti string, integer, atau nilai Boolean), atau data terstruktur (seperti tipe kompleks).

Kerangka Kerja Entitas memungkinkan Anda untuk membuat kueri, menyisipkan, memperbarui, dan menghapus data, menggunakan objek Common Language Runtime (CLR) yang dikenal sebagai entitas. Kerangka Kerja Entitas memetakan entitas dan hubungan yang ditentukan dalam model Anda ke database. Ini juga menyediakan fasilitas untuk -

  • Mewujudkan data yang dikembalikan dari database sebagai objek entitas
  • Lacak perubahan yang dilakukan pada objek
  • Tangani konkurensi
  • Menyebarkan perubahan objek kembali ke database
  • Ikat objek ke kontrol

Kelas utama yang bertanggung jawab untuk berinteraksi dengan data sebagai objek adalah System.Data.Entity.DbContext. API DbContext tidak dirilis sebagai bagian dari .NET Framework. Agar lebih fleksibel dan sering dengan merilis fitur baru ke Code First dan DbContext API, tim Entity Framework mendistribusikan EntityFramework.dll melalui fitur distribusi NuGet Microsoft.

  • NuGet memungkinkan Anda untuk menambahkan referensi ke proyek .NET Anda dengan menarik DLL yang relevan langsung ke proyek Anda dari Web.

  • Ekstensi Visual Studio yang disebut Library Package Manager menyediakan cara mudah untuk menarik rakitan yang sesuai dari Web ke dalam proyek Anda.

  • DbContext API sebagian besar ditargetkan untuk menyederhanakan interaksi Anda dengan Entity Framework.

  • Ini juga mengurangi jumlah metode dan properti yang Anda perlukan untuk mengakses tugas yang umum digunakan.

  • Di versi sebelumnya dari Entity Framework, tugas-tugas ini seringkali rumit untuk ditemukan dan dikodekan.

  • Kelas konteks mengelola objek entitas selama waktu proses, yang mencakup mengisi objek dengan data dari database, mengubah pelacakan, dan mempertahankan data ke database.

Mendefinisikan Kelas Turunan DbContext

Cara yang disarankan untuk bekerja dengan konteks adalah dengan mendefinisikan kelas yang berasal dari DbContext dan mengekspos properti DbSet yang mewakili kumpulan entitas yang ditentukan dalam konteks. Jika Anda bekerja dengan EF Designer, konteksnya akan dibuatkan untuk Anda. Jika Anda bekerja dengan Code First, Anda biasanya akan menulis konteksnya sendiri.

Kode berikut adalah contoh sederhana yang menunjukkan bahwa UniContext diturunkan dari DbContext.

  • Anda dapat menggunakan properti otomatis dengan DbSet seperti getter dan setter.

  • Itu juga membuat kode yang jauh lebih bersih, tetapi Anda tidak diharuskan menggunakannya untuk tujuan membuat DbSet ketika Anda tidak memiliki logika lain untuk diterapkan.

public class UniContext : DbContext {
   public UniContext() : base("UniContext") { }
   public DbSet<Student> Students { get; set; }
   public DbSet<Enrollment> Enrollments { get; set; }
   public DbSet<Course> Courses { get; set; }
}
  • Sebelumnya, EDM digunakan untuk menghasilkan kelas konteks yang diturunkan dari kelas ObjectContext.

  • Bekerja dengan ObjectContext agak rumit.

  • DbContext adalah pembungkus di sekitar ObjectContext yang sebenarnya mirip dengan ObjectContext dan berguna dan mudah di semua model pengembangan seperti Code First, Model First dan Database First.

Pertanyaan

Ada tiga jenis kueri yang dapat Anda gunakan seperti -

  • Menambahkan entitas baru.
  • Mengubah atau memperbarui nilai properti dari entitas yang sudah ada.
  • Menghapus entitas yang sudah ada.

Menambahkan Entitas Baru

Menambahkan objek baru dengan Entity Framework semudah membuat instance baru dari objek Anda dan mendaftarkannya menggunakan metode Add di DbSet. Kode berikut ini untuk saat Anda ingin menambahkan siswa baru ke database.

private static void AddStudent() {

   using (var context = new UniContext()) {

      var student = new Student {
         LastName = "Khan", 
         FirstMidName = "Ali", 
         EnrollmentDate = DateTime.Parse("2005-09-01") 
      };

      context.Students.Add(student); 
      context.SaveChanges();

   }
}

Mengubah Entitas yang Ada

Mengubah objek yang ada semudah memperbarui nilai yang ditetapkan ke properti yang ingin Anda ubah dan memanggil SaveChanges. Dalam kode berikut, nama belakang Ali telah diubah dari Khan menjadi Aslam.

private static void AddStudent() {

   private static void ChangeStudent() {

      using (var context = new UniContext()) {

         var student = (from d in context.Students
            where d.FirstMidName == "Ali" select d).Single();
         student.LastName = "Aslam";
         context.SaveChanges();

      }
   }
}

Menghapus Entitas yang Ada

Untuk menghapus entitas menggunakan Entity Framework, Anda menggunakan metode Hapus di DbSet. Hapus pekerjaan untuk entitas yang sudah ada dan yang baru ditambahkan. Memanggil Hapus pada entitas yang telah ditambahkan tetapi belum disimpan ke database akan membatalkan penambahan entitas. Entitas dihapus dari pelacak perubahan dan tidak lagi dilacak oleh DbContext. Memanggil Hapus pada entitas yang ada yang sedang dilacak perubahannya akan mendaftarkan entitas untuk dihapus saat SaveChanges dipanggil berikutnya. Contoh berikut menunjukkan contoh di mana siswa dihapus dari database yang nama depannya adalah Ali.

private static void DeleteStudent() {

   using (var context = new UniContext()) {
      var bay = (from d in context.Students where d.FirstMidName == "Ali" select d).Single();
      context.Students.Remove(bay);
      context.SaveChanges();
   }
}

Dalam Entity Framework, ada dua jenis entitas yang memungkinkan pengembang menggunakan kelas data kustom mereka sendiri bersama dengan model data tanpa membuat modifikasi apa pun pada kelas datanya sendiri.

  • Entitas POCO
  • Proxy Dinamis

Entitas POCO

  • POCO adalah singkatan dari objek CLR "biasa-lama" yang dapat digunakan sebagai objek domain yang ada dengan model data Anda.

  • Kelas data POCO yang dipetakan ke entitas ditentukan dalam model data.

  • Ini juga mendukung sebagian besar perilaku kueri, menyisipkan, memperbarui, dan menghapus yang sama sebagai tipe entitas yang dihasilkan oleh alat Model Data Entitas.

  • Anda dapat menggunakan template POCO untuk menghasilkan tipe entitas yang mengabaikan ketekunan dari model konseptual.

Mari kita lihat contoh Model Data Entitas Konseptual berikut.

Untuk menghasilkan entitas POCO untuk model Entitas di atas -

Step 1- Klik kanan pada jendela desainer. Ini akan menampilkan dialog berikut.

Step 2 - Pilih Add Code Generation Item ...

Step 3 - Pilih EF 6.x DbContext Generator, tulis nama lalu klik tombol Add.

Anda akan melihat di explorer solusi Anda bahwa template POCODemo.Context.tt dan POCODemo.tt dibuat.

POCODemo.Context menghasilkan DbContext dan kumpulan objek yang dapat Anda kembalikan dan gunakan untuk kueri, katakanlah untuk konteks, Siswa dan Kursus, dll.

Template lainnya berhubungan dengan semua jenis Mahasiswa, Kursus, dll. Berikut adalah kode untuk kelas Mahasiswa yang dihasilkan secara otomatis dari Model Entitas.

namespace ConsoleApplication1 {

   using System;
   using System.Collections.Generic;

   public partial class Student {

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2214:DoNotCallOverridableMethodsInConstructors")]

      public Student() {
         this.Enrollments = new HashSet<Enrollment>();
      }

      public int ID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
      public System.DateTime EnrollmentDate { get; set; }

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         CA2227:CollectionPropertiesShouldBeReadOnly")]

      public virtual ICollection<Enrollment> Enrollments { get; set; }

   }
}

Kelas serupa dibuat untuk tabel Kursus dan Pendaftaran dari Model Entitas.

Proxy Dinamis

Saat membuat instance dari tipe entitas POCO, Entity Framework sering membuat instance dari tipe turunan yang dihasilkan secara dinamis yang bertindak sebagai proxy untuk entitas. Dapat juga dikatakan bahwa itu adalah kelas proxy runtime seperti kelas pembungkus entitas POCO.

  • Anda dapat mengganti beberapa properti entitas untuk melakukan tindakan secara otomatis saat properti diakses.

  • Mekanisme ini digunakan untuk mendukung pemuatan lambat hubungan dan pelacakan perubahan otomatis.

  • Teknik ini juga berlaku untuk model yang dibuat dengan Code First dan EF Designer.

Jika Anda ingin Entity Framework mendukung pemuatan lambat dari objek terkait dan melacak perubahan dalam kelas POCO, maka kelas POCO harus memenuhi persyaratan berikut -

  • Kelas data khusus harus dideklarasikan dengan akses publik.

  • Kelas data khusus tidak boleh disegel.

  • Kelas data khusus tidak boleh abstrak.

  • Kelas data khusus harus memiliki konstruktor publik atau dilindungi yang tidak memiliki parameter.

  • Gunakan konstruktor yang dilindungi tanpa parameter jika Anda ingin metode CreateObject digunakan untuk membuat proxy untuk entitas POCO.

  • Memanggil metode CreateObject tidak menjamin pembuatan proxy: kelas POCO harus mengikuti persyaratan lain yang dijelaskan dalam topik ini.

  • Kelas tidak dapat menerapkan antarmuka IEntityWithChangeTracker atau IEntityWithRelationships karena kelas proxy menerapkan antarmuka ini.

  • Opsi ProxyCreationEnabled harus disetel ke true.

Contoh berikut adalah kelas entitas proxy dinamis.

public partial class Course {

   public Course() {
      this.Enrollments = new HashSet<Enrollment>();
   }

   public int CourseID { get; set; }
   public string Title { get; set; }
   public int Credits { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Untuk menonaktifkan pembuatan objek proxy, setel nilai properti ProxyCreationEnabled ke false.

Dalam database relasional, hubungan adalah situasi yang ada antara tabel database relasional melalui kunci asing. Kunci Asing (FK) adalah kolom atau kombinasi kolom yang digunakan untuk menetapkan dan menegakkan tautan antara data dalam dua tabel. Diagram berikut berisi tiga tabel.

  • Student
  • Course
  • Enrollment

Pada diagram di atas, Anda dapat melihat semacam asosiasi / hubungan antar tabel. Ada tiga tipe hubungan antar tabel dan hubungan antara tabel berbeda bergantung pada bagaimana kolom terkait ditentukan.

  • Hubungan Satu-ke-Banyak
  • Hubungan Banyak ke Banyak
  • Hubungan Satu-ke-Satu

Hubungan Satu-ke-Banyak

  • Hubungan satu-ke-banyak adalah jenis hubungan yang paling umum.

  • Dalam jenis hubungan ini, baris dalam tabel A dapat memiliki banyak baris yang cocok dalam tabel B, tetapi baris dalam tabel B hanya dapat memiliki satu baris yang cocok dalam tabel A.

  • Kunci asing ditentukan dalam tabel yang mewakili banyak ujung hubungan.

  • Misalnya, dalam diagram di atas tabel Siswa dan Pendaftaran memiliki hubungan satu-tomany, setiap siswa mungkin memiliki banyak pendaftaran, tetapi setiap pendaftaran hanya dimiliki oleh satu siswa.

Dalam kerangka entitas, hubungan ini juga dapat dibuat dengan kode. Berikut adalah contoh kelas Mahasiswa dan Pendaftaran yang terkait dengan hubungan satu ke banyak.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

public class Enrollment {

   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
	
   public Grade? Grade { get; set; }
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }
}

Pada kode di atas, Anda dapat melihat bahwa kelas Siswa berisi kumpulan Pendaftaran, tetapi kelas Pendaftaran memiliki satu Objek Siswa.

Hubungan Banyak ke Banyak

Dalam hubungan banyak-ke-banyak, baris dalam tabel A dapat memiliki banyak baris yang cocok dalam tabel B, dan sebaliknya.

  • Anda dapat membuat hubungan seperti itu dengan menentukan tabel ketiga, yang disebut tabel persimpangan, yang kunci utamanya terdiri dari kunci asing dari tabel A dan tabel B.

  • Misalnya, tabel siswa dan kursus memiliki hubungan banyak ke banyak yang ditentukan oleh hubungan satu ke banyak dari setiap tabel ini ke tabel pendaftaran.

Kode berikut berisi kelas Kursus dan dua kelas di atas, yaitu, Student dan Enrollment.

public class Course {
   [DatabaseGenerated(DatabaseGeneratedOption.None)]
	
   public int CourseID { get; set; }
   public string Title { get; set; }
	
   public int Credits { get; set; } 
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Anda dapat melihat bahwa kelas Kursus dan kelas Siswa memiliki koleksi objek Pendaftaran yang membuat hubungan banyak-ke-banyak melalui kelas persimpangan Pendaftaran.

Hubungan Satu-ke-Satu

  • Dalam hubungan satu-ke-satu, baris dalam tabel A tidak dapat memiliki lebih dari satu baris yang cocok dalam tabel B, dan sebaliknya.

  • Hubungan satu-ke-satu dibuat jika kedua kolom terkait adalah kunci utama atau memiliki batasan unik.

  • Dalam hubungan satu-ke-satu, kunci utama bertindak sebagai kunci asing dan tidak ada kolom kunci asing terpisah untuk tabel mana pun.

Jenis hubungan ini tidak umum karena sebagian besar informasi yang terkait dengan cara ini semuanya ada dalam satu tabel. Anda dapat menggunakan hubungan satu-ke-satu untuk -

  • Bagilah tabel dengan banyak kolom.
  • Pisahkan bagian dari tabel untuk alasan keamanan.
  • Menyimpan data yang berumur pendek dan dapat dengan mudah dihapus hanya dengan menghapus tabel.
  • Simpan informasi yang hanya berlaku untuk subset dari tabel utama.

Kode berikut untuk menambahkan nama kelas StudentProfile yang berisi id email siswa dan password.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
   public virtual StudentProfile StudentProfile { get; set; }
}

public class StudentProfile {

   public StudentProfile() {}
   public int ID { get; set; }
   public string Email { get; set; }
   public string Password { get; set; }
	
   public virtual Student Student { get; set; }
}

Anda dapat melihat bahwa kelas entitas siswa berisi properti navigasi StudentProfile dan StudentProfile berisi properti navigasi siswa.

Setiap siswa hanya memiliki satu Email dan kata sandi untuk login di domain universitas. Informasi ini dapat ditambahkan ke tabel Siswa tetapi untuk alasan keamanan dipisahkan ke tabel lain.

Seumur hidup

Masa pakai konteks dimulai saat instance dibuat dan berakhir saat instance dibuang atau dikumpulkan sampahnya.

  • Konteks seumur hidup adalah keputusan yang sangat penting untuk dibuat saat kita menggunakan ORM.

  • Konteksnya bekerja seperti cache entitas, jadi itu berarti ini menyimpan referensi ke semua entitas yang dimuat yang mungkin tumbuh sangat cepat dalam konsumsi memori dan juga dapat menyebabkan kebocoran memori.

  • Pada diagram di bawah ini, Anda dapat melihat alur kerja data tingkat atas dari aplikasi ke database melalui Konteks dan sebaliknya.

Siklus Hidup Entitas

Siklus Hidup Entitas menjelaskan proses di mana Entitas dibuat, ditambahkan, dimodifikasi, dihapus, dll. Entitas memiliki banyak status selama masa pakainya. Sebelum melihat cara mengambil status entitas, mari kita lihat apa itu status entitas. Negara bagian adalah enum tipeSystem.Data.EntityState yang mendeklarasikan nilai-nilai berikut -

  • Added: Entitas tersebut ditandai sebagai ditambahkan.

  • Deleted: Entitas tersebut ditandai sebagai dihapus.

  • Modified: Entitas telah diubah.

  • Unchanged: Entitas belum diubah.

  • Detached: Entitas tidak dilacak.

Status Perubahan dalam Siklus Hidup Entitas

Terkadang status entitas diatur secara otomatis oleh konteksnya, tetapi juga dapat dimodifikasi secara manual oleh pengembang. Meskipun semua kombinasi sakelar dari satu kondisi ke kondisi lain dimungkinkan, tetapi beberapa di antaranya tidak ada artinya. Sebagai contoh,Added entitas ke Deleted negara bagian, atau sebaliknya.

Mari kita bahas tentang berbagai negara bagian.

Status Tidak Berubah

  • Jika entitas tidak berubah, itu terikat ke konteks tetapi belum dimodifikasi.

  • Secara default, entitas yang diambil dari database berada dalam status ini.

  • Ketika entitas dilampirkan ke konteks (dengan metode Lampirkan), itu juga berada dalam status Tidak Berubah.

  • Konteks tidak dapat melacak perubahan pada objek yang tidak direferensikan, jadi ketika dilampirkan, diasumsikan tidak berubah.

Status Terpisah

  • Terpisah adalah status default dari entitas yang baru dibuat karena konteksnya tidak dapat melacak pembuatan objek apa pun di kode Anda.

  • Ini benar bahkan jika Anda membuat instance entitas di dalam blok penggunaan konteks.

  • Terpisah bahkan status entitas yang diambil dari database saat pelacakan dinonaktifkan.

  • Ketika sebuah entitas terlepas, itu tidak terikat pada konteksnya, jadi statusnya tidak dilacak.

  • Ini dapat dibuang, dimodifikasi, digunakan dalam kombinasi dengan kelas lain, atau digunakan dengan cara lain yang mungkin Anda perlukan.

  • Karena tidak ada pelacakan konteks, itu tidak ada artinya bagi Kerangka Kerja Entitas.

Status Ditambahkan

  • Saat entitas berada dalam status Ditambahkan, Anda memiliki beberapa opsi. Nyatanya, Anda hanya bisa melepaskannya dari konteksnya.

  • Biasanya, meskipun Anda memodifikasi beberapa properti, statusnya tetap Ditambahkan, karena memindahkannya ke Dimodifikasi, Tidak Berubah, atau Dihapus tidak masuk akal.

  • Ini adalah entitas baru dan tidak memiliki korespondensi dengan baris di database.

  • Ini adalah prasyarat mendasar untuk berada di salah satu negara bagian tersebut (tetapi aturan ini tidak ditegakkan oleh konteksnya).

Status yang Dimodifikasi

  • Ketika sebuah entitas diubah, itu berarti itu dalam keadaan Tidak Berubah dan kemudian beberapa properti diubah.

  • Setelah entitas memasuki status Dimodifikasi, entitas dapat dipindahkan ke status Terpisah atau Dihapus, tetapi tidak dapat memutar kembali ke status Tidak Berubah meskipun Anda memulihkan nilai aslinya secara manual.

  • Itu bahkan tidak dapat diubah menjadi Ditambahkan, kecuali Anda melepaskan dan menambahkan entitas ke konteks, karena baris dengan ID ini sudah ada di database, dan Anda akan mendapatkan pengecualian waktu proses saat mempertahankannya.

Status Dihapus

  • Entitas memasuki status Dihapus karena tidak Berubah atau Dimodifikasi dan kemudian metode DeleteObject digunakan.

  • Ini adalah status paling ketat, karena tidak ada gunanya mengubah dari status ini ke nilai lain selain Terpisah.

Itu usingpernyataan jika Anda ingin semua sumber daya yang kontrol konteks akan dibuang di akhir blok. Saat Anda menggunakanusing pernyataan, kemudian kompilator secara otomatis membuat blok coba / akhirnya dan panggilan dibuang di blok akhirnya.

using (var context = new UniContext()) {

   var student = new Student {
      LastName = "Khan", 
      FirstMidName = "Ali", 
      EnrollmentDate = DateTime.Parse("2005-09-01")
   };

   context.Students.Add(student);
   context.SaveChanges();
}

Saat bekerja dengan konteks jangka panjang pertimbangkan hal berikut -

  • Saat Anda memuat lebih banyak objek dan referensinya ke dalam memori, konsumsi memori dari konteks dapat meningkat dengan cepat. Ini dapat menyebabkan masalah kinerja.

  • Ingatlah untuk membuang konteks saat tidak lagi diperlukan.

  • Jika pengecualian menyebabkan konteks berada dalam keadaan tidak dapat dipulihkan, seluruh aplikasi dapat dihentikan.

  • Peluang untuk mengalami masalah terkait konkurensi meningkat seiring dengan meningkatnya jarak antara waktu ketika data dikueri dan diperbarui.

  • Saat bekerja dengan aplikasi Web, gunakan contoh konteks per permintaan.

  • Saat bekerja dengan Windows Presentation Foundation (WPF) atau Windows Forms, gunakan contoh konteks per formulir. Ini memungkinkan Anda menggunakan fungsionalitas pelacakan perubahan yang disediakan konteks.

Aturan Thumb

Web Applications

  • Sekarang menjadi praktik umum dan terbaik bahwa untuk aplikasi web, konteks digunakan per permintaan.

  • Dalam aplikasi web, kami menangani permintaan yang sangat singkat tetapi menampung semua transaksi server, oleh karena itu, mereka memiliki durasi yang tepat untuk konteks tempat tinggal.

Desktop Applications

  • Untuk aplikasi desktop, seperti Win Forms / WPF, dll. Konteksnya digunakan per formulir / dialog / halaman.

  • Karena kami tidak ingin memiliki konteks sebagai tunggal untuk aplikasi kami, kami akan membuangnya saat kami berpindah dari satu bentuk ke bentuk lainnya.

  • Dengan cara ini, kita akan mendapatkan banyak kemampuan konteks dan tidak akan menderita karena implikasi dari konteks jangka panjang.

Kerangka Entitas menyediakan tiga pendekatan untuk membuat model entitas dan masing-masing memiliki pro dan kontra sendiri.

  • Kode Pertama
  • Database Pertama
  • Model Pertama

Dalam bab ini, kami akan menjelaskan secara singkat pendekatan pertama kode. Beberapa pengembang lebih suka bekerja dengan Desainer dalam Kode sementara yang lain lebih suka bekerja dengan kode mereka. Untuk pengembang tersebut, Entity Framework memiliki alur kerja pemodelan yang disebut sebagai Kode Pertama.

  • Alur kerja pemodelan Code First menargetkan database yang tidak ada dan Code First akan membuatnya.

  • Ini juga dapat digunakan jika Anda memiliki database kosong dan kemudian Code First akan menambahkan tabel baru juga.

  • Code First memungkinkan Anda untuk menentukan model Anda menggunakan kelas C # atau VB.Net.

  • Konfigurasi tambahan secara opsional dapat dilakukan menggunakan atribut pada kelas dan properti Anda atau dengan menggunakan API yang lancar.

Mengapa Kode Dulu?

  • Code First benar-benar terdiri dari satu set potongan puzzle. Pertama adalah kelas domain Anda.

  • Kelas domain tidak ada hubungannya dengan Entity Framework. Mereka hanyalah item dari domain bisnis Anda.

  • Entity Framework, kemudian, memiliki konteks yang mengelola interaksi antara kelas-kelas tersebut dan database Anda.

  • Konteksnya tidak spesifik untuk Code First. Ini adalah fitur Entity Framework.

  • Code First menambahkan pembuat model yang memeriksa kelas Anda yang dikelola konteks, lalu menggunakan sekumpulan aturan atau konvensi untuk menentukan bagaimana kelas dan hubungan tersebut mendeskripsikan model, dan bagaimana model tersebut harus dipetakan ke database Anda.

  • Semua ini terjadi saat runtime. Anda tidak akan pernah melihat model ini, hanya ada di memori.

  • Code First memiliki kemampuan untuk menggunakan model itu untuk membuat database jika diperlukan.

  • Itu juga dapat memperbarui database jika model berubah, menggunakan fitur yang disebut Migrasi Pertama Kode.

Dalam bab ini, mari kita pelajari cara membuat model data entitas di desainer menggunakan alur kerja yang disebut sebagai Model Pertama.

  • Model First sangat bagus untuk saat Anda memulai proyek baru yang bahkan belum memiliki database.

  • Model disimpan dalam file EDMX dan dapat dilihat dan diedit di Entity Framework Designer.

  • Di Model First, Anda menentukan model Anda di desainer Entity Framework lalu menghasilkan SQL, yang akan membuat skema database agar sesuai dengan model Anda dan kemudian Anda menjalankan SQL untuk membuat skema di database Anda.

  • Kelas yang berinteraksi dengan Anda dalam aplikasi Anda secara otomatis dibuat dari file EDMX.

Berikut adalah contoh sederhana untuk membuat proyek konsol baru menggunakan pendekatan Model First.

Step 1 - Buka Visual Studio dan pilih File → New → Project

Step 2 - Pilih Installed → Templates → Visual C # → Windows dari panel kiri dan kemudian di panel tengah, pilih Console Application.

Step 3 - Masukkan EFModelFirstDemo di bidang Nama.

Step 4 - Untuk membuat model, pertama-tama klik kanan pada proyek konsol Anda di penjelajah solusi dan pilih Tambah → Item Baru…

Dialog berikut akan terbuka.

Step 5 - Pilih ADO.NET Entity Data Model dari panel tengah dan masukkan nama ModelFirstDemoDB di kolom Name.

Step 6 - Klik tombol Add yang akan meluncurkan dialog Entity Data Model Wizard.

Step 7- Pilih model Empty EF Designer dan klik tombol Next. Entity Framework Designer terbuka dengan model kosong. Sekarang kita dapat mulai menambahkan entitas, properti, dan asosiasi ke model.

Step 8- Klik kanan pada permukaan desain dan pilih Properties. Di jendela Properties, ubah Entity Container Name menjadi ModelFirstDemoDBContext.

Step 9 - Klik kanan pada permukaan desain dan pilih Add New → Entity…

Dialog Add Entity akan terbuka seperti yang ditunjukkan pada gambar berikut.

Step 10 - Masukkan Mahasiswa sebagai nama entitas dan ID Mahasiswa sebagai nama properti dan klik Ok.

Step 11 - Klik kanan pada entitas baru pada permukaan desain dan pilih Tambah Baru → Properti Skalar, masukkan Nama sebagai nama properti.

Step 12 - Masukkan FirstName lalu tambahkan dua properti skalar seperti LastName dan EnrollmentDate.

Step 13 - Tambahkan dua lagi Entities Course dan Enrollment dengan mengikuti semua langkah yang disebutkan di atas dan juga tambahkan beberapa properti Skalar seperti yang ditunjukkan pada langkah-langkah berikut.

Step 14 - Kami memiliki tiga entitas dalam Desainer Visual, mari tambahkan beberapa asosiasi atau hubungan di antara mereka.

Step 15 - Klik kanan pada permukaan desain dan pilih Add New → Association…

Step 16 - Buat salah satu ujung hubungan menunjuk ke Siswa dengan kelipatan satu dan ujung lainnya mengarah ke Pendaftaran dengan kelipatan banyak.

Step 17 - Ini berarti bahwa seorang Siswa memiliki banyak Pendaftaran dan Pendaftaran milik satu Siswa.

Step 18 - Pastikan kotak Add foreign key to 'Post' Entity dicentang dan klik OK.

Step 19 - Demikian pula, tambahkan satu asosiasi lagi antara Kursus dan Pendaftaran.

Step 20 - Model data Anda akan terlihat seperti layar berikut setelah menambahkan asosiasi antar entitas.

Kami sekarang memiliki model sederhana yang kami dapat menghasilkan database dari dan digunakan untuk membaca dan menulis data. Mari lanjutkan dan buat database.

Step 1 - Klik kanan pada permukaan desain dan pilih Hasilkan Database dari Model…

Step 2 - Anda dapat memilih database yang ada atau membuat koneksi baru dengan mengklik New Connection…

Step 3 - Untuk membuat Database baru, klik New Connection ...

Step 4 - Masukkan nama Server dan nama database.

Step 5 - Klik Berikutnya.

Step 6- Klik Selesai. Ini akan menambahkan file * .edmx.sql dalam proyek. Anda dapat menjalankan skrip DDL di Visual Studio dengan membuka file .sql, lalu klik kanan dan pilih Execute.

Step 7 - Dialog berikut akan ditampilkan untuk menghubungkan ke database.

Step 8 - Jika eksekusi berhasil, Anda akan melihat pesan berikut.

Step 9 - Masuk ke server explorer, Anda akan melihat bahwa database dibuat dengan tiga tabel yang ditentukan.

Selanjutnya, kita perlu menukar model kita untuk menghasilkan kode yang menggunakan API DbContext.

Step 1 - Klik kanan pada tempat kosong model Anda di EF Designer dan pilih Tambahkan Item Pembuatan Kode ...

Anda akan melihat bahwa dialog Add New Item berikut terbuka.

Step 2 - Pilih EF 6.x DbContext Generator di panel tengah dan masukkan ModelFirstDemoModel di kolom Name.

Step 3 - Anda akan melihat di penjelajah solusi Anda bahwa template ModelFirstDemoModel.Context.tt dan ModelFirstDemoModel.tt dibuat.

ModelFirstDemoModel.Context menghasilkan DbCcontext dan kumpulan objek yang dapat Anda kembalikan dan gunakan untuk membuat kueri, misalnya untuk konteks, Siswa dan Kursus, dll.

Template lainnya berhubungan dengan semua jenis Mahasiswa, Kursus, dll. Berikut adalah kelas Mahasiswa, yang dihasilkan secara otomatis dari Model Entitas.

Berikut adalah kode C # di mana beberapa data dimasukkan dan diambil dari database.

using System;
using System.Linq;

namespace EFModelFirstDemo {

   class Program {

      static void Main(string[] args) {

         using (var db = new ModelFirstDemoDBContext()) {

            // Create and save a new Student

            Console.Write("Enter a name for a new Student: ");
            var firstName = Console.ReadLine();

            var student = new Student {
               StudentID = 1,
               FirstName = firstName
            };
				
            db.Students.Add(student);
            db.SaveChanges();
				
            var query = from b in db.Students
               orderby b.FirstName select b;

            Console.WriteLine("All student in the database:");

            foreach (var item in query) {
               Console.WriteLine(item.FirstName);
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
         }
      }
   }
}

Ketika kode di atas dijalankan, Anda akan menerima output berikut -

Enter a name for a new Student:
Ali Khan
All student in the database:
Ali Khan
Press any key to exit...

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Dalam bab ini, mari kita pelajari tentang membuat model data entitas dengan pendekatan Database First.

  • Pendekatan Database First memberikan alternatif untuk pendekatan Kode Pertama dan Model Pertama untuk Model Data Entitas. Ini membuat kode model (kelas, properti, DbContext, dll.) Dari database dalam proyek dan kelas-kelas itu menjadi penghubung antara database dan pengontrol.

  • Pendekatan Pertama Database membuat kerangka entitas dari database yang ada. Kami menggunakan semua fungsi lainnya, seperti model / sinkronisasi database dan pembuatan kode, dengan cara yang sama kami menggunakannya dalam pendekatan Model First.

Mari kita ambil contoh sederhana. Kami sudah memiliki database yang berisi 3 tabel seperti yang ditunjukkan pada gambar berikut.

Step 1 - Mari buat proyek konsol baru dengan nama DatabaseFirstDemo.

Step 2 - Untuk membuat model, pertama-tama klik kanan pada proyek konsol Anda di explorer solusi dan pilih Add → New Items…

Step 3 - Pilih ADO.NET Entity Data Model dari panel tengah dan masukkan nama DatabaseFirstModel di kolom Name.

Step 4 - Klik tombol Add yang akan meluncurkan dialog Entity Data Model Wizard.

Step 5 - Pilih EF Designer dari database dan klik tombol Next.

Step 6 - Pilih database yang ada dan klik Next.

Step 7 - Pilih Entity Framework 6.x dan klik Next.

Step 8 - Pilih semua tampilan tabel dan prosedur tersimpan yang ingin Anda sertakan dan klik Selesai.

Anda akan melihat bahwa model Entitas dan kelas POCO dihasilkan dari database.

Sekarang mari kita ambil semua siswa dari database dengan menulis kode berikut di file program.cs.

using System;
using System.Linq;

namespace DatabaseFirstDemo {

   class Program {

      static void Main(string[] args) {

         using (var db = new UniContextEntities()) {

            var query = from b in db.Students
               orderby b.FirstMidName select b;

            Console.WriteLine("All All student in the database:");

            foreach (var item in query) {
               Console.WriteLine(item.FirstMidName +" "+ item.LastName);
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
         }
      }
   }
}

Ketika program di atas dijalankan, Anda akan menerima output berikut -

All student in the database:
Ali Khan
Arturo   finand
Bill Gates
Carson Alexander
Gytis Barzdukas
Laura Norman
Meredith Alonso
Nino Olivetto
Peggy Justice
Yan Li
Press any key to exit...

Ketika program di atas dijalankan, Anda akan melihat semua nama siswa yang sebelumnya dimasukkan ke dalam database.

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Di bab ini, mari kita fokus pada membangun model dengan Designer atau Database First atau hanya menggunakan Code First. Berikut adalah beberapa pedoman yang akan membantu Anda memutuskan alur kerja pemodelan mana yang akan dipilih.

  • Kita telah melihat contoh pemodelan Code First, pemodelan Database First, dan alur kerja pemodelan Model First.

  • Alur kerja Database First dan Model First menggunakan Designer tetapi satu dimulai dengan database untuk membuat model dan yang lainnya dimulai pada model untuk membuat database.

  • Bagi pengembang yang tidak ingin menggunakan Visual Designer plus pembuatan kode, Entity Framework memiliki alur kerja yang sama sekali berbeda yang disebut Code First.

  • Alur kerja khas untuk Code First sangat bagus untuk aplikasi baru di mana Anda bahkan tidak memiliki database. Anda menentukan kelas dan kode Anda dan kemudian membiarkan Kode Pertama mencari tahu seperti apa database Anda seharusnya.

  • Dimungkinkan juga untuk memulai Code First dengan database dan itu membuat Code First sedikit kontradiksi. Tetapi ada alat untuk memungkinkan Anda merekayasa balik database menjadi kelas-kelas yang merupakan cara terbaik untuk memulai pengkodean.

Diberikan opsi ini, mari kita lihat Pohon Keputusan.

  • Jika Anda lebih suka bekerja dengan Visual Designer dalam kode yang dihasilkan, maka Anda akan ingin memilih salah satu alur kerja yang melibatkan EF Designer. Jika database Anda sudah ada, maka Database First adalah jalur Anda.

  • Jika Anda ingin menggunakan Visual Designer pada proyek baru tanpa database, maka Anda akan ingin menggunakan Model First.

  • Jika Anda hanya ingin bekerja dengan kode dan bukan Desainer, maka Kode Pertama mungkin cocok untuk Anda bersama dengan opsi untuk menggunakan alat yang mengubah basis data menjadi kelas.

  • Jika Anda memiliki kelas yang sudah ada, maka taruhan terbaik Anda adalah menggunakannya dengan Kode Pertama.

Di bab sebelumnya, Anda telah mempelajari tiga cara berbeda untuk menentukan model data entitas.

  • Dua di antaranya, Database First dan Model First, bergantung pada desainer Entity Framework yang dikombinasikan dengan pembuatan kode.

  • Yang ketiga, Kode Pertama, memungkinkan Anda melewati perancang visual dan hanya menulis kode Anda sendiri.

  • Terlepas dari jalur mana yang Anda pilih, Anda akan mendapatkan kelas domain dan satu atau lebih kelas Entity Framework DbContext memungkinkan Anda untuk mengambil dan menyimpan data yang relevan dengan kelas tersebut.

API DbContext di aplikasi Anda digunakan sebagai jembatan antara kelas dan database Anda. DbContext adalah salah satu kelas terpenting dalam Entity Framework.

  • Ini memungkinkan untuk mengekspresikan dan mengeksekusi kueri.

  • Ini mengambil hasil kueri dari database dan mengubahnya menjadi contoh kelas model kami.

  • Itu dapat melacak perubahan pada entitas, termasuk menambah dan menghapus, dan kemudian memicu pembuatan pernyataan sisipkan, perbarui dan hapus yang dikirim ke database sesuai permintaan.

Berikut ini adalah kelas konteks iklan domain di mana kita akan melakukan operasi yang berbeda dalam bab ini. Ini adalah contoh yang sama yang telah kita buat di chapater, Database First Approach.

Implementasi Kelas Konteks

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Core.Objects;
using System.Linq;

namespace DatabaseFirstDemo {

   public partial class UniContextEntities : DbContext {

      public UniContextEntities(): base("name = UniContextEntities") {}

      protected override void OnModelCreating(DbModelBuilder modelBuilder) {
         throw new UnintentionalCodeFirstException();
      }

      public virtual DbSet<Course> Courses { get; set; }
      public virtual DbSet<Enrollment> Enrollments { get; set; }
      public virtual DbSet<Student> Students { get; set; }
   }
}

Implementasi Kelas Domain

Kelas kursus

namespace DatabaseFirstDemo {

   using System;
   using System.Collections.Generic;
	
   public partial class Course {

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2214:DoNotCallOverridableMethodsInConstructors")]

      public Course() {
         this.Enrollments = new HashSet<Enrollment>();
      }
	
      public int CourseID { get; set; }
      public string Title { get; set; }
      public int Credits { get; set; }
	
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2227:CollectionPropertiesShouldBeReadOnly")]
			
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }
}

Kelas siswa

namespace DatabaseFirstDemo {

   using System;
   using System.Collections.Generic; 

   public partial class Student {

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2214:DoNotCallOverridableMethodsInConstructors")]

      public Student() {
         this.Enrollments = new HashSet<Enrollment>();
      }

      public int ID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
      public System.DateTime EnrollmentDate { get; set; }

      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", 
         "CA2227:CollectionPropertiesShouldBeReadOnly")]
			
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }
}

Kelas pendaftaran

namespace DatabaseFirstDemo {

   using System;
   using System.Collections.Generic; 

   public partial class Enrollment {

      public int EnrollmentID { get; set; }
      public int CourseID { get; set; }
      public int StudentID { get; set; }
      public Nullable<int> Grade { get; set; }
		
      public virtual Course Course { get; set; }
      public virtual Student Student { get; set; }
   }
}

Buat Operasi

Menambahkan objek baru dengan Entity Framework semudah membuat instance baru dari objek Anda dan mendaftarkannya menggunakan metode Add di DbSet. Kode berikut memungkinkan Anda menambahkan siswa baru ke database.

class Program {

   static void Main(string[] args) {

      var newStudent = new Student();

      //set student name

      newStudent.FirstMidName = "Bill";
      newStudent.LastName = "Gates";
      newStudent.EnrollmentDate = DateTime.Parse("2015-10-21");
      newStudent.ID = 100;

      //create DBContext object

      using (var dbCtx = new UniContextEntities()) {

         //Add Student object into Students DBset
         dbCtx.Students.Add(newStudent);

         // call SaveChanges method to save student into database
         dbCtx.SaveChanges();
      }
   }
}

Perbarui Operasi

Mengubah objek yang ada semudah memperbarui nilai yang ditetapkan ke properti yang ingin Anda ubah dan memanggil SaveChanges. Misalnya, kode berikut ini digunakan untuk mengubah nama belakang Ali dari Khan menjadi Aslam.

using (var context = new UniContextEntities()) {

   var student = (from d in context.Students where d.FirstMidName == "Ali" select d).Single();
   student.LastName = "Aslam";
   context.SaveChanges();
}

Hapus Operasi

Untuk menghapus entitas menggunakan Entity Framework, Anda menggunakan metode Hapus di DbSet. Hapus pekerjaan untuk entitas yang sudah ada dan yang baru ditambahkan. Memanggil Hapus pada entitas yang telah ditambahkan tetapi belum disimpan ke database akan membatalkan penambahan entitas. Entitas dihapus dari pelacak perubahan dan tidak lagi dilacak oleh DbContext. Memanggil Hapus pada entitas yang ada yang sedang dilacak perubahannya akan mendaftarkan entitas untuk dihapus saat SaveChanges dipanggil berikutnya. Contoh berikut adalah kode di mana siswa dihapus dari database yang nama depannya adalah Ali.

using (var context = new UniContextEntities()) {
   var bay = (from d in context.Students where d.FirstMidName == "Ali" select d).Single();
   context.Students.Remove(bay);
   context.SaveChanges();
}

Baca Operasi

Membaca data yang ada dari database sangatlah sederhana. Berikut adalah kode di mana semua data dari tabel siswa diambil dan kemudian program akan ditampilkan dengan nama depan dan belakang siswa dalam urutan abjad.

using (var db = new UniContextEntities()) {

   var query = from b in db.Students orderby b.FirstMidName select b;
   Console.WriteLine("All All student in the database:");

   foreach (var item in query) {
      Console.WriteLine(item.FirstMidName +" "+ item.LastName);
   }

   Console.WriteLine("Press any key to exit...");
   Console.ReadKey();
}

Setiap pengembang akses data menghadapi kesulitan saat menjawab pertanyaan tentang konkurensi data, “Apa yang terjadi jika lebih dari satu orang mengedit data yang sama pada waktu yang sama?”

  • Yang lebih beruntung di antara kita berurusan dengan aturan bisnis yang mengatakan "tidak masalah, yang terakhir menang."

  • Dalam kasus ini, konkurensi bukanlah masalah. Kemungkinan besar, ini tidak sesederhana itu, dan tidak ada solusi yang tepat untuk menyelesaikan setiap skenario sekaligus.

  • Secara default, Entity Framework akan mengambil jalur "yang terakhir menang," yang berarti bahwa pembaruan terbaru diterapkan bahkan jika orang lain memperbarui data antara waktu data diambil dan waktu data disimpan.

Mari kita ambil contoh untuk memahaminya dengan lebih baik. Contoh berikut menambahkan kolom baru VersionNo di tabel Kursus.

Pergi ke desainer dan klik kanan pada jendela desainer dan pilih model pembaruan dari database…

Anda akan melihat bahwa kolom lain ditambahkan di Entitas Kursus.

Klik kanan pada kolom VersionNo yang baru dibuat dan pilih Properties dan ubah ConcurrencyMode menjadi Fixed seperti yang ditunjukkan pada gambar berikut.

Dengan ConcurrencyMode dari Course.VersionNo disetel ke Fixed, kapan pun Kursus diperbarui, perintah Perbarui akan mencari Kursus menggunakan EntityKey dan properti VersionNo-nya.

Mari kita lihat skenario sederhana. Dua pengguna mengambil kursus yang sama pada saat yang sama dan pengguna 1 mengubah judul kursus itu menjadi Matematika dan menyimpan perubahan sebelum pengguna 2. Nanti ketika pengguna 2 mengubah judul kursus itu yang diambil sebelum pengguna 1 menyimpan perubahannya, dalam hal itu kasus pengguna 2 akan mendapatkan pengecualian konkurensi"User2: Optimistic Concurrency exception occured".

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;

namespace DatabaseFirstDemo {

   class Program {

      static void Main(string[] args) {

         Course c1 = null;
         Course c2 = null;

         //User 1 gets Course

         using (var context = new UniContextEntities()) {
            context.Configuration.ProxyCreationEnabled = false;
            c1 = context.Courses.Where(s ⇒ s.CourseID == 1).Single();
         }

         //User 2 also get the same Course

         using (var context = new UniContextEntities()) {
            context.Configuration.ProxyCreationEnabled = false;
            c2 = context.Courses.Where(s ⇒ s.CourseID == 1).Single();
         }

         //User 1 updates Course Title
         c1.Title = "Edited from user1";

         //User 2 updates Course Title
         c2.Title = "Edited from user2";

         //User 1 saves changes first

         using (var context = new UniContextEntities()) {

            try {
               context.Entry(c1).State = EntityState.Modified;
               context.SaveChanges();
            } catch (DbUpdateConcurrencyException ex) {
               Console.WriteLine("User1: Optimistic Concurrency exception occurred");
            }
         }

         //User 2 saves changes after User 1.
         //User 2 will get concurrency exection
         //because CreateOrModifiedDate is different in the database

         using (var context = new UniContextEntities()) {

            try {
               context.Entry(c2).State = EntityState.Modified;
               context.SaveChanges();
            } catch (DbUpdateConcurrencyException ex) {
               Console.WriteLine("User2: Optimistic Concurrency exception occurred");
            }
         }
      }
   }
}

Di semua versi Entity Framework, kapan pun Anda menjalankan SaveChanges()untuk memasukkan, memperbarui atau menghapus database, kerangka kerja akan membungkus operasi itu dalam sebuah transaksi. Saat Anda menjalankan SaveChanges, konteks secara otomatis memulai transaksi dan melakukan atau memutarnya kembali tergantung pada apakah persistensi berhasil.

  • Ini semua transparan bagi Anda, dan Anda tidak perlu menghadapinya.

  • Transaksi ini hanya berlangsung cukup lama untuk menjalankan operasi dan kemudian selesai.

  • Saat Anda menjalankan operasi serupa lainnya, transaksi baru akan dimulai.

Entity Framework 6 menyediakan berikut ini -

Database.BeginTransaction ()

  • Ini adalah metode sederhana dan mudah dalam DbContext yang ada untuk memulai dan menyelesaikan transaksi bagi pengguna.

  • Ini memungkinkan beberapa operasi untuk digabungkan dalam transaksi yang sama dan karenanya semuanya berkomitmen atau semuanya dibatalkan sebagai satu.

  • Ini juga memungkinkan pengguna untuk lebih mudah menentukan tingkat isolasi untuk transaksi.

Database.UseTransaction ()

  • Ini memungkinkan DbContext untuk menggunakan transaksi, yang dimulai di luar Kerangka Entitas.

Mari kita lihat contoh berikut di mana beberapa operasi dilakukan dalam satu transaksi. Kode tersebut adalah sebagai -

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         using (var dbContextTransaction = context.Database.BeginTransaction()) {

            try {

               Student student = new Student() {
                  ID = 200, 
                  FirstMidName = "Ali", 
                  LastName = "Khan", 
                  EnrollmentDate = DateTime.Parse("2015-12-1")
               };

               context.Students.Add(student);

               context.Database.ExecuteSqlCommand(@"UPDATE Course SET Title = 
                  'Calculus'" + "WHERE CourseID = 1045");

               var query = context.Courses.Where(c ⇒ c.CourseID == 1045);

               foreach (var item in query) {
                  Console.WriteLine(item.CourseID.ToString()
                     + " " + item.Title + " " + item.Credits);
               }

               context.SaveChanges();
               var query1 = context.Students.Where(s ⇒ s.ID == 200);

               foreach (var item in query1) {
                  Console.WriteLine(item.ID.ToString() 
                     + " " + item.FirstMidName + " " + item.LastName);
               }

               dbContextTransaction.Commit();
            } catch (Exception) {
               dbContextTransaction.Rollback();
            }

         }
      }
   }
}
  • Memulai transaksi membutuhkan koneksi toko yang mendasarinya terbuka.

  • Jadi memanggil Database.BeginTransaction () akan membuka koneksi, jika belum dibuka.

  • Jika DbContextTransaction membuka koneksi maka itu akan menutupnya ketika Dispose () dipanggil.

Tampilan adalah objek yang berisi data yang diperoleh dengan kueri yang telah ditentukan sebelumnya. Tampilan adalah objek atau tabel virtual yang kumpulan hasilnya berasal dari kueri. Ini sangat mirip dengan tabel nyata karena berisi kolom dan baris data. Berikut adalah beberapa penggunaan umum tampilan -

  • Filter data tabel yang mendasari
  • Filter data untuk tujuan keamanan
  • Pusatkan data yang didistribusikan di beberapa server
  • Buat kumpulan data yang dapat digunakan kembali

Tampilan dapat digunakan dengan cara yang sama seperti Anda menggunakan tabel. Untuk menggunakan view sebagai entitas, pertama-tama Anda perlu menambahkan tampilan database ke EDM. Setelah menambahkan tampilan ke model Anda, maka Anda dapat bekerja dengannya dengan cara yang sama seperti entitas normal kecuali untuk operasi Buat, Perbarui, dan Hapus.

Mari kita lihat, bagaimana menambahkan view ke dalam model dari database.

Step 1 - Buat proyek Aplikasi Konsol baru.

Step 2 - Klik kanan pada proyek di penjelajah solusi dan pilih Tambah → Item Baru.

Step 3 - Pilih ADO.NET Entity Data Model dari panel tengah dan masukkan nama ViewModel di kolom Name.

Step 4 - Klik tombol Add yang akan meluncurkan dialog Entity Data Model Wizard.

Step 5 - Pilih EF Designer dari database dan klik tombol Next.

Step 6 - Pilih database yang ada dan klik Next.

Step 7 - Pilih Entity Framework 6.x dan klik Next.

Step 8 - Pilih tabel dan tampilan dari database Anda dan klik Selesai.

Anda dapat melihat di jendela desainer bahwa tampilan dibuat dan Anda dapat menggunakannya dalam program sebagai entitas.

Di penjelajah solusi, Anda dapat melihat bahwa kelas MyView juga dihasilkan dari database.

Mari kita ambil contoh di mana semua data diambil dari tampilan. Berikut kodenya -

class Program {

   static void Main(string[] args) {

      using (var db = new UniContextEntities()) {

         var query = from b in db.MyViews
            orderby b.FirstMidName select b;

         Console.WriteLine("All student in the database:");

         foreach (var item in query) {
            Console.WriteLine(item.FirstMidName + " " + item.LastName);
         }

         Console.WriteLine("Press any key to exit...");
         Console.ReadKey();
      }
   }
}

Ketika kode di atas dijalankan, Anda akan menerima output berikut -

All student in the database:
Ali Khan
Arturo   finand
Bill Gates
Carson Alexander
Gytis Barzdukas
Laura Norman
Meredith Alonso
Nino Olivetto
Peggy Justice
Yan Li
Press any key to exit...

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Indeks adalah struktur data di disk yang didasarkan pada tabel dan tampilan. Indeks membuat pengambilan data lebih cepat dan efisien, dalam banyak kasus. Namun, membebani tabel atau tampilan dengan indeks secara tidak menyenangkan dapat memengaruhi kinerja operasi lain seperti penyisipan atau pembaruan.

  • Pengindeksan adalah fitur baru dalam kerangka entitas tempat Anda dapat meningkatkan kinerja aplikasi Code First Anda dengan mengurangi waktu yang diperlukan untuk membuat kueri data dari database.

  • Anda dapat menambahkan indeks ke database Anda menggunakan Index atribut, dan mengganti default Unique dan Clustered pengaturan untuk mendapatkan indeks yang paling sesuai dengan skenario Anda.

Mari kita lihat kode berikut di mana atribut Indeks ditambahkan di kelas Kursus untuk CourseID.

public partial class Course {

   public Course() {
      this.Enrollments = new HashSet<Enrollment>();
   }

   [Index]
   public int CourseID { get; set; }
   public string Title { get; set; }
	
   public int Credits { get; set; }
   public byte[] VersionNo { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

Kunci yang dibuat di atas tidak unik, tidak berkerumun. Ada kelebihan beban yang tersedia untuk menggantikan default ini -

  • Untuk membuat indeks menjadi indeks Clustered, Anda perlu menentukan IsClustered = true

  • Demikian pula, Anda juga dapat membuat indeks menjadi indeks unik dengan menentukan IsUnique = true

Mari kita lihat kode C # berikut di mana sebuah indeks dikelompokkan dan unik.

public partial class Course {

   public Course() {
      this.Enrollments = new HashSet<Enrollment>();
   }

   [Index(IsClustered = true, IsUnique = true)]
   public int CourseID { get; set; }
   public string Title { get; set; }
	
   public int Credits { get; set; }
   public byte[] VersionNo { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Atribut indeks dapat digunakan untuk membuat indeks unik dalam database. Namun, ini tidak berarti bahwa EF akan dapat menjelaskan tentang keunikan kolom saat menangani hubungan, dll. Fitur ini biasanya disebut sebagai dukungan untuk "batasan unik".

Kerangka Kerja Entitas memungkinkan Anda untuk menggunakan prosedur yang disimpan dalam Model Data Entitas, bukan, atau dikombinasikan dengan, pembuatan perintah otomatisnya.

  • Anda dapat menggunakan prosedur tersimpan untuk menjalankan logika yang telah ditentukan sebelumnya pada tabel database, dan banyak organisasi memiliki kebijakan yang memerlukan penggunaan prosedur tersimpan ini.

  • Itu juga dapat menentukan bahwa EF harus menggunakan prosedur tersimpan Anda untuk memasukkan, memperbarui, atau menghapus entitas.

  • Meskipun perintah yang dibangun secara dinamis aman, efisien, dan secara umum sama baiknya atau lebih baik daripada yang Anda tulis sendiri, ada banyak kasus di mana prosedur tersimpan sudah ada dan praktik perusahaan Anda mungkin membatasi penggunaan tabel secara langsung.

  • Atau, Anda mungkin hanya ingin memiliki kontrol eksplisit atas apa yang dijalankan di penyimpanan dan lebih memilih untuk membuat prosedur tersimpan.

Contoh berikut membuat proyek baru dari File → New → Project.

Step 1 - Pilih Aplikasi Konsol dari panel tengah dan masukkan StoredProceduresDemo di bidang nama.

Step 2 - Di Server explorer, klik kanan pada database Anda.

Step 3 - Pilih New Query dan masukkan kode berikut di editor T-SQL untuk menambahkan tabel baru di database Anda.

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = 
   OBJECT_ID(N'[dbo].[StudentGrade]') AND type in (N'U'))

BEGIN

   CREATE TABLE [dbo].[StudentGrade](

      [EnrollmentID] [int] IDENTITY(1,1) NOT NULL,
      [CourseID] [int] NOT NULL,
      [StudentID] [int] NOT NULL,
      [Grade] [decimal](3, 2) NULL,

      CONSTRAINT [PK_StudentGrade] PRIMARY KEY CLUSTERED (
         [EnrollmentID] ASC
      )

      WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]

   ) ON [PRIMARY]

END
GO

Step 4 - Klik kanan pada editor dan pilih Execute.

Step 5- Klik kanan pada database Anda dan klik refresh. Anda akan melihat tabel yang baru ditambahkan di database Anda.

Step 6 - Di Penjelajah server, klik kanan lagi pada database Anda.

Step 7 - Pilih Kueri Baru dan masukkan kode berikut di editor T-SQL untuk menambahkan prosedur tersimpan di database Anda, yang akan mengembalikan nilai Siswa.

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = 
   OBJECT_ID(N'[dbo].[GetStudentGrades]') AND type in (N'P', N'PC'))

BEGIN

   EXEC dbo.sp_executesql @statement = N'
   CREATE PROCEDURE [dbo].[GetStudentGrades]
   @StudentID int
   AS
   SELECT EnrollmentID, Grade, CourseID, StudentID FROM dbo.StudentGrade 
   WHERE StudentID = @StudentID
   '
END
GO

Step 8 - Klik kanan pada editor dan pilih Execute.

Step 9- Klik kanan pada database Anda dan klik refresh. Anda akan melihat bahwa prosedur tersimpan dibuat di database Anda.

Step 10 - Klik kanan pada nama proyek di Solution Explorer dan pilih Add → New Item.

Step 11 - Kemudian pilih ADO.NET Entity Data Model di panel Templates.

Step 12 - Masukkan SPModel sebagai nama, lalu klik Tambahkan.

Step 13 - Di kotak dialog Choose Model Contents, pilih EF designer from database, dan kemudian klik Next.

Step 14 - Pilih database Anda dan klik Next.

Step 15 - Dalam kotak dialog Pilih Objek Database Anda, klik tabel, tampilan.

Step 16 - Pilih fungsi GetStudentGradesForCourse yang terletak di bawah node Stored Procedures and Functions dan klik Finish.

Step 17 - Pilih View → Other Windows → Entity Data Model Browser dan klik kanan GetStudentGrades di bawah Function Imports dan pilih Edit.

Ini akan menghasilkan dialog berikut.

Step 18 - Klik pada tombol radio Entities dan pilih StudentGrade dari kotak kombo sebagai tipe pengembalian dari prosedur tersimpan ini dan klik Ok.

Mari kita lihat kode C # berikut di mana semua nilai akan diambil dengan meneruskan ID siswa sebagai parameter dalam prosedur tersimpan GetStudentGrades.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         int studentID = 22;
         var studentGrades = context.GetStudentGrades(studentID);

         foreach (var student in studentGrades) {
            Console.WriteLine("Course ID: {0}, Title: {1}, Grade: {2} ", 
               student.CourseID, student.Course.Title, student.Grade);
         }

         Console.ReadKey();

      }
   }
}

Ketika kode di atas dikompilasi dan dijalankan, Anda akan menerima output berikut -

Course ID: 4022, Title: Microeconomics, Grade: 3.00
Course ID: 4041, Title: Macroeconomics, Grade: 3.50

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Dalam bab ini, mari kita lihat bagaimana membuat perubahan pada entitas yang tidak dilacak oleh konteks. Entitas yang tidak dilacak oleh konteks dikenal sebagai entitas 'terputus'.

  • Untuk sebagian besar aplikasi tingkat tunggal, di mana antarmuka pengguna dan lapisan akses database berjalan dalam proses aplikasi yang sama, Anda mungkin hanya akan melakukan operasi pada entitas yang dilacak oleh konteks.

  • Operasi pada entitas yang terputus jauh lebih umum dalam aplikasi N-Tier.

  • Aplikasi N-Tier melibatkan pengambilan beberapa data di server dan mengembalikannya, melalui jaringan, ke mesin klien.

  • Aplikasi klien kemudian memanipulasi data ini sebelum mengembalikannya ke server untuk disimpan.

Berikut adalah dua langkah yang perlu diambil dengan grafik entitas terputus atau bahkan entitas terputus tunggal.

  • Lampirkan entitas dengan contoh konteks baru dan buat konteks sadar tentang entitas ini.

  • Tetapkan EntityStates yang sesuai untuk entitas ini secara manual.

Mari kita lihat kode berikut di mana entitas Mahasiswa ditambahkan dengan dua entitas Pendaftaran.

class Program {

   static void Main(string[] args) {

      var student = new Student {

         ID = 1001,
         FirstMidName = "Wasim",
         LastName = "Akram", 

         EnrollmentDate = DateTime.Parse("2015-10-10"), 
            Enrollments = new List<Enrollment> {

               new Enrollment{EnrollmentID = 2001,CourseID = 4022, StudentID = 1001 },
               new Enrollment{EnrollmentID = 2002,CourseID = 4025, StudentID = 1001 },
         }
      };

      using (var context = new UniContextEntities()) {

         context.Students.Add(student);
         Console.WriteLine("New Student ({0} {1}): {2}", 
            student.FirstMidName, student.LastName, context.Entry(student).State);

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0} State: {1}", 
               enrollment.EnrollmentID, context.Entry(enrollment).State);
         }

         Console.WriteLine("Press any key to exit...");
         Console.ReadKey();
      }
   } 
}
  • Kode tersebut membuat instance Student baru, yang juga mereferensikan dua instance Pendaftaran baru di properti Enrollments-nya.

  • Kemudian Siswa baru ditambahkan ke konteks menggunakan metode Tambah.

  • Setelah Siswa ditambahkan, kode menggunakan metode DbContext.Entry untuk mendapatkan akses ke informasi pelacakan perubahan yang dimiliki Kerangka Kerja Entitas tentang Siswa baru.

  • Dari informasi pelacakan perubahan ini, properti Status digunakan untuk menuliskan status entitas saat ini.

  • Proses ini kemudian diulangi untuk setiap Pendaftaran yang baru dibuat yang dirujuk dari Siswa baru. Jika Anda menjalankan aplikasi, Anda akan menerima output berikut -

New Student   (Wasim  Akram): Added
Enrollment ID: 2001 State: Added
Enrollment ID: 2002 State: Added
Press any key to exit...

Sementara DbSet.Add digunakan untuk memberi tahu Entity Framework tentang entitas baru, DbSet.Attach digunakan untuk memberi tahu Entity Framework tentang entitas yang ada. Metode Lampirkan akan menandai entitas dalam status Tidak Berubah.

Mari kita lihat kode C # berikut di mana entitas terputus dilampirkan dengan DbContext.

class Program {

   static void Main(string[] args) {

      var student = new Student {

         ID = 1001,
         FirstMidName = "Wasim",
         LastName = "Akram",
         EnrollmentDate = DateTime.Parse("2015-10-10"), 

         Enrollments = new List<Enrollment> {
            new Enrollment { EnrollmentID = 2001, CourseID = 4022, StudentID = 1001 },
            new Enrollment { EnrollmentID = 2002, CourseID = 4025, StudentID = 1001 },
         }
			
      };

      using (var context = new UniContextEntities()) {

         context.Students.Attach(student);
         Console.WriteLine("New Student ({0} {1}): {2}", 
            student.FirstMidName, student.LastName, context.Entry(student).State);

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0} State: {1}", enrollment.EnrollmentID, 
               context.Entry(enrollment).State);
         }

         Console.WriteLine("Press any key to exit...");
         Console.ReadKey();
      }
   }
}

Ketika kode di atas dijalankan dengan metode Attach (), Anda akan menerima output berikut.

New Student   (Wasim  Akram): Unchanged
Enrollment ID: 2001 State: Unchanged
Enrollment ID: 2002 State: Unchanged
Press any key to exit...

Dalam bab ini, mari kita pelajari cara memetakan Fungsi Nilai Tabel (TVF) menggunakan Entity Framework Designer dan cara memanggil TVF dari kueri LINQ.

  • TVF saat ini hanya didukung di alur kerja Database First.

  • Ini pertama kali diperkenalkan di Entity Framework versi 5.

  • Untuk menggunakan TVF, Anda harus menargetkan .NET Framework 4.5 atau lebih tinggi.

  • Ini sangat mirip dengan prosedur tersimpan tetapi dengan satu perbedaan utama, yaitu, hasil TVF dapat disusun. Ini berarti hasil dari TVF dapat digunakan dalam kueri LINQ sedangkan hasil prosedur tersimpan tidak bisa.

Mari kita lihat contoh berikut untuk membuat proyek baru dari File → New → Project.

Step 1 - Pilih Aplikasi Konsol dari panel tengah dan masukkan TableValuedFunctionDemo di bidang nama.

Step 2 - Di Server explorer, klik kanan pada database Anda.

Step 3 - Pilih New Query dan masukkan kode berikut di editor T-SQL untuk menambahkan tabel baru di database Anda.

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id =
   OBJECT_ID(N'[dbo].[StudentGrade]') AND type in (N'U'))

BEGIN

   CREATE TABLE [dbo].[StudentGrade](

      [EnrollmentID] [int] IDENTITY(1,1) NOT NULL,
      [CourseID] [int] NOT NULL,
      [StudentID] [int] NOT NULL,
      [Grade] [decimal](3, 2) NULL,

      CONSTRAINT [PK_StudentGrade] PRIMARY KEY CLUSTERED ([EnrollmentID] ASC)

      WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]

   ) ON [PRIMARY]

END
GO

Step 4 - Klik kanan pada editor dan pilih Execute.

Step 5- Klik kanan pada database Anda dan klik refresh. Anda akan melihat tabel yang baru ditambahkan di database Anda.

Step 6- Sekarang buat fungsi yang akan mengembalikan nilai siswa untuk kursus. Masukkan kode berikut di editor T-SQL.

CREATE FUNCTION [dbo].[GetStudentGradesForCourse]

(@CourseID INT)

RETURNS TABLE

RETURN
   SELECT [EnrollmentID],
      [CourseID],
      [StudentID],
      [Grade]
   FROM   [dbo].[StudentGrade]
   WHERE  CourseID = @CourseID

Step 7 - Klik kanan pada editor dan pilih Execute.

Sekarang Anda dapat melihat bahwa fungsinya dibuat.

Step 8 - Klik kanan pada nama proyek di Solution Explorer dan pilih Add → New Item.

Step 9 - Kemudian pilih ADO.NET Entity Data Model di panel Templates.

Step 10 - Masukkan TVFModel sebagai nama, lalu klik Tambahkan.

Step 11 - Di kotak dialog Choose Model Contents, pilih EF designer from database, dan kemudian klik Next.

Step 12 - Pilih database Anda dan klik Next.

Step 13 - Dalam kotak dialog Pilih Objek Database Anda pilih tabel, tampilan.

Step 14 - Pilih fungsi GetStudentGradesForCourse yang terletak di bawah node Stored Procedures and Functions dan klik Finish.

Step 15 - Pilih View → Other Windows → Entity Data Model Browser dan klik kanan GetStudentGradesForCourse di bawah Function Imports dan pilih Edit.

Anda akan melihat dialog berikut.

Step 16 - Klik pada radio button Entities dan pilih Enrollment dari combobox sebagai tipe return dari Function ini dan klik Ok.

Mari kita lihat kode C # berikut di mana semua nilai siswa akan diambil yang terdaftar di Course ID = 4022 di database.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         var CourseID = 4022;

         // Return all the best students in the Microeconomics class.
         var students = context.GetStudentGradesForCourse(CourseID);

         foreach (var result in students) {
            Console.WriteLine("Student ID:  {0}, Grade: {1}",
               result.StudentID, result.Grade);
         }

         Console.ReadKey();
      }
   }
}

Ketika kode di atas dikompilasi dan dijalankan, Anda akan menerima output berikut -

Student ID: 1, Grade: 2
Student ID: 4, Grade: 4
Student ID: 9, Grade: 3.5

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Dalam Entity Framework Anda dapat melakukan kueri dengan kelas entitas Anda menggunakan LINQ. Anda juga dapat menjalankan kueri menggunakan SQL mentah secara langsung ke database menggunakan DbCOntext. Teknik ini dapat diterapkan secara merata ke model yang dibuat dengan Code First dan EF Designer.

Kueri SQL pada Entitas yang Ada

Metode SqlQuery di DbSet memungkinkan kueri SQL mentah untuk ditulis yang akan mengembalikan instance entitas. Objek yang dikembalikan akan dilacak oleh konteksnya sama seperti jika dikembalikan oleh kueri LINQ. Misalnya -

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         var students = context.Students.SqlQuery("SELECT * FROM dbo.Student").ToList();

         foreach (var student in students) {
            string name = student.FirstMidName + " " + student.LastName;
            Console.WriteLine("ID: {0}, Name: {1}, \tEnrollment Date {2} ",
               student.ID, name, student.EnrollmentDate.ToString());
         }

         Console.ReadKey();
      }
   }
}

Kode di atas akan mengambil semua siswa dari database.

Kueri SQL untuk Tipe Non-entitas

Kueri SQL yang mengembalikan instance jenis apa pun, termasuk jenis primitif, dapat dibuat menggunakan metode SqlQuery pada kelas Database. Misalnya -

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         var studentNames = context.Database.SqlQuery
            <string>("SELECT FirstMidName FROM dbo.Student").ToList();

         foreach (var student in studentNames) {
            Console.WriteLine("Name: {0}", student);
         }

         Console.ReadKey();
      }
   }
}

Perintah SQL ke Database

Metode ExecuteSqlCommnad digunakan dalam mengirimkan perintah non-kueri ke database, seperti perintah Sisipkan, Perbarui atau Hapus. Mari kita lihat kode berikut di mana nama depan siswa diperbarui sebagai ID = 1

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         //Update command

         int noOfRowUpdated = context.Database.ExecuteSqlCommand("Update 
            student set FirstMidName = 'Ali' where ID = 1");

         context.SaveChanges();

         var student = context.Students.SqlQuery("SELECT * FROM
            dbo.Student where ID = 1").Single();

         string name = student.FirstMidName + " " + student.LastName;

         Console.WriteLine("ID: {0}, Name: {1}, \tEnrollment Date {2} ", 
            student.ID, name, student.EnrollmentDate.ToString());

         Console.ReadKey();
      }
   }
}

Kode di atas akan mengambil semua nama depan siswa dari database.

Dalam Entity Framework, fitur ini memungkinkan Anda untuk menentukan properti pada kelas domain yang merupakan tipe enum dan memetakannya ke kolom database dengan tipe integer. Entity Framework kemudian akan mengonversi nilai database ke dan dari enum yang relevan saat melakukan kueri dan menyimpan data.

  • Jenis yang dihitung memiliki semua jenis manfaat saat bekerja dengan properti yang memiliki jumlah respons tetap.

  • Keamanan dan keandalan aplikasi meningkat saat Anda menggunakan pencacahan.

  • Pencacahan mempersulit pengguna untuk membuat kesalahan, dan masalah seperti serangan injeksi tidak ada.

  • Dalam Entity Framework, enumerasi dapat memiliki tipe dasar berikut -

    • Byte
    • Int16
    • Int32
    • Int64
    • SByte
  • Tipe dasar default dari elemen enumerasi adalah int.

  • Secara default, pencacah pertama bernilai 0, dan nilai setiap pencacah berturut-turut dinaikkan 1.

Mari kita lihat contoh berikut di mana kita akan membuat entitas di desainer dan kemudian akan menambahkan beberapa properti.

Step 1 - Buat proyek baru dari File → Baru → Opsi menu proyek.

Step 2 - Di panel kiri, pilih Aplikasi Konsol.

Step 3 - Masukkan EFEnumDemo sebagai nama proyek dan klik OK.

Step 4 - Klik kanan pada nama proyek di Solution Explorer dan pilih Add → New Item menu option.

Step 5 - Pilih ADO.NET Entity Data Model di panel Templates.

Step 6 - Masukkan EFEnumModel.edmx untuk nama file, lalu klik Tambah.

Step 7 - Di halaman Panduan Model Data Entitas, pilih Model desainer EF Kosong.

Step 8 - Klik Selesai

Step 9 - Kemudian klik kanan pada jendela designer dan pilih Add → Entity.

Kotak dialog Entitas Baru muncul seperti yang ditunjukkan pada gambar berikut.

Step 10 - Masukkan Departemen sebagai nama Entitas dan DeptID sebagai nama properti, biarkan tipe Properti sebagai Int32 dan klik OK.

Step 11 - Klik kanan entitas dan pilih Add New → Scalar Property.

Step 12 - Ubah nama properti baru menjadi DeptName.

Step 13 - Ubah tipe properti baru menjadi Int32 (secara default, properti baru adalah tipe String).

Step 14 - Untuk mengubah tipe, buka jendela Properties dan ubah properti Type menjadi Int32.

Step 15 - Di Entity Framework Designer, klik kanan properti Name, pilih Convert to enum.

Step 16 - Di kotak dialog Tambah Jenis Enum, masukkan Nama Departemen untuk Nama Jenis Enum, ubah Jenis Dasar ke Int32, lalu tambahkan anggota berikut ke jenis: Fisika, Kimia, Komputer, dan Ekonomi.

Step 17 - Klik Ok.

Jika Anda beralih ke jendela Model Browser, Anda akan melihat bahwa tipe tersebut juga telah ditambahkan ke node Jenis Enum.

Mari menghasilkan database dari model dengan mengikuti semua langkah yang disebutkan dalam bab Pendekatan Model Pertama.

Step 1 - Klik kanan permukaan Entity Designer dan pilih Generate Database from Model.

Kotak Dialog Pilih Koneksi Data Anda dari Panduan Buat Database akan ditampilkan.

Step 2 - Klik tombol Koneksi Baru.

Step 3 - Masukkan nama server dan EnumDemo untuk database dan klik OK.

Step 4 - Dialog yang menanyakan apakah Anda ingin membuat database baru akan muncul, klik Ya.

Step 5- Klik Next dan Create Database Wizard menghasilkan data definition language (DDL) untuk membuat database. Sekarang klik Selesai.

Step 6 - Klik kanan pada T-SQL Editor dan pilih Execute.

Step 7 - Untuk melihat skema yang dibuat, klik kanan pada nama database di SQL Server Object Explorer dan pilih Refresh.

Anda akan melihat tabel Departemen di database.

Mari kita lihat contoh berikut di mana beberapa objek Departemen baru ke konteks ditambahkan dan disimpan. Dan kemudian buka kembali departemen Komputer.

class Program {

   static void Main(string[] args) {

      using (var context = new EFEnumModelContainer()) {

         context.Departments.Add(new Department { DeptName = DepartmentNames.Physics});
         context.Departments.Add(new Department { DeptName = DepartmentNames.Computer});
         context.Departments.Add(new Department { DeptName = DepartmentNames.Chemistry});
         context.Departments.Add(new Department { DeptName = DepartmentNames.Economics});

         context.SaveChanges();

         var department = (
            from d in context.Departments
            where d.DeptName == DepartmentNames.Computer
            select d
         ).FirstOrDefault();

         Console.WriteLine(
            "Department ID: {0}, Department Name: {1}", 
               department.DeptID, department.DeptName
         );

         Console.ReadKey();
      }
   }
}

Ketika kode di atas dijalankan, Anda akan menerima output berikut -

Department ID: 2, Department Name: Computer

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Asynchronous programmingmelibatkan pelaksanaan operasi di latar belakang sehingga utas utama dapat melanjutkan operasinya sendiri. Dengan cara ini thread utama dapat menjaga antarmuka pengguna tetap responsif saat thread latar belakang memproses tugas yang sedang dikerjakan.

  • Entity Framework 6.0 mendukung operasi asinkron untuk membuat kueri dan menyimpan data.

  • Operasi asinkron dapat membantu aplikasi Anda dengan cara berikut -

    • Jadikan aplikasi Anda lebih responsif terhadap interaksi pengguna
    • Tingkatkan kinerja aplikasi Anda secara keseluruhan
  • Anda dapat menjalankan operasi asinkron dengan berbagai cara. Tetapi kata kunci async / await diperkenalkan di .NET Framework 4.5 yang membuat pekerjaan Anda sederhana.

  • Satu-satunya hal yang perlu Anda ikuti adalah pola async / await seperti yang diilustrasikan oleh fragmen kode berikut.

Mari kita lihat contoh berikut (tanpa menggunakan async / await) di mana metode DatabaseOperations menyimpan siswa baru ke database dan kemudian mengambil semua siswa dari database dan pada akhirnya beberapa pesan tambahan dicetak di konsol.

class Program {

   static void Main(string[] args) {
      Console.WriteLine("Database Operations Started");
      DatabaseOperations();
		
      Console.WriteLine();
      Console.WriteLine("Database Operations Completed");
      Console.WriteLine();
      Console.WriteLine("Entity Framework Tutorials");
      Console.ReadKey();
   }

   public static void DatabaseOperations() {

      using (var context = new UniContextEntities()) {

         // Create a new student and save it

         context.Students.Add(new Student {
            FirstMidName = "Akram", 
            LastName = "Khan", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())});

         Console.WriteLine("Calling SaveChanges.");
         context.SaveChanges();
         Console.WriteLine("SaveChanges completed.");

         // Query for all Students ordered by first name

         var students = (from s in context.Students
            orderby s.FirstMidName select s).ToList();

         // Write all students out to Console

         Console.WriteLine();
         Console.WriteLine("All Student:");

         foreach (var student in students) {
            string name = student.FirstMidName + " " + student.LastName;
            Console.WriteLine(" " + name);
         }
      }
   }
}

Ketika kode di atas dijalankan, Anda akan menerima output berikut -

Calling SaveChanges.
SaveChanges completed.
All Student:
Akram Khan
Ali Khan
Ali Alexander
Arturo Anand
Bill Gates
Gytis Barzdukas
Laura  Nornan
Meredith fllonso
Nino Olioetto
Peggy Justice
Yan Li

Entity Framework Tutorials

Mari gunakan async baru dan await kata kunci dan buat perubahan berikut ke Program.cs

  • Tambahkan namespace System.Data.Entity yang akan memberikan metode ekstensi async EF.

  • Tambahkan namespace System.Threading.Tasks yang akan memungkinkan kita menggunakan jenis Tugas.

  • Memperbarui DatabaseOperations untuk ditandai sebagai async dan mengembalikan a Task.

  • Panggil SaveChanges versi Async dan tunggu penyelesaiannya.

  • Panggil versi Async dari ToList dan tunggu hasilnya.

class Program {

   static void Main(string[] args) {
      var task = DatabaseOperations();
      Console.WriteLine();
      Console.WriteLine("Entity Framework Tutorials");
      task.Wait();
      Console.ReadKey();
   }

   public static async Task DatabaseOperations() {

      using (var context = new UniContextEntities()) {

         // Create a new blog and save it

         context.Students.Add(new Student {
            FirstMidName = "Salman", 
            LastName = "Khan", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())});

         Console.WriteLine("Calling SaveChanges.");
         await context.SaveChangesAsync();
         Console.WriteLine("SaveChanges completed.");

         // Query for all Students ordered by first name

         var students = await (from s in context.Students 
            orderby s.FirstMidName select s).ToListAsync();

         // Write all students out to Console

         Console.WriteLine();
         Console.WriteLine("All Student:");

         foreach (var student in students) {
            string name = student.FirstMidName + " " + student.LastName; 
            Console.WriteLine(" " + name);
         }
      }
   }
}

Saat dieksekusi, ini akan menghasilkan keluaran sebagai berikut.

Calling SaveChanges.
Entity Framework Tutorials
SaveChanges completed.
All Student:
Akram Khan
Ali Khan
Ali Alexander
Arturo Anand
Bill Gates
Gytis Barzdukas
Laura  Nornan
Meredith fllonso
Nino Olioetto
Peggy Justice
Salman Khan
Yan Li

Sekarang kodenya tidak sinkron, Anda dapat mengamati aliran eksekusi yang berbeda dari program Anda.

  • SaveChanges mulai mendorong Student baru ke database dan kemudian metode DatabaseOperations kembali (meskipun belum selesai dijalankan) dan alur program dalam metode Utama terus berlanjut.

  • Pesan kemudian ditulis ke konsol.

  • Utas yang dikelola diblokir pada panggilan Tunggu hingga operasi database selesai. Setelah selesai, sisa DatabaseOperations kami akan dieksekusi.

  • SaveChanges selesai.

  • Mengambil semua siswa dari database dan ditulis ke Konsol.

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Kerangka Kerja Entitas sekarang memungkinkan Anda memanfaatkan Kerangka Kerja Entitas tanpa memaksa setiap bagian aplikasi Anda untuk mengetahui Kerangka Kerja Entitas, memisahkan entitas dari infrastruktur. Anda bisa membuat kelas yang bisa fokus pada aturan bisnis mereka tanpa memperhatikan bagaimana mereka dipertahankan (di mana data disimpan dan bagaimana data bolak-balik di antara objek Anda).

Membuat Entitas Ketidaktahuan yang Persisten

Paragraf sebelumnya menjelaskan metode yang tidak memiliki pengetahuan mendalam tentang sumber data yang dikonsumsi. Ini menyoroti esensi dari ketidaktahuan persistensi, yaitu ketika kelas Anda dan banyak lapisan aplikasi kita di sekitarnya tidak peduli bagaimana data disimpan.

  • Dalam versi .NET 3.5 Entity Framework, jika Anda ingin menggunakan kelas yang sudah ada sebelumnya, Anda diminta untuk memodifikasinya dengan memaksa mereka untuk berasal dari EntityObject.

  • Di .NET 4 ini tidak lagi diperlukan. Anda tidak perlu mengubah entitas Anda agar mereka dapat berpartisipasi dalam operasi Entity Framework.

  • Hal ini memungkinkan kami untuk membangun aplikasi yang mencakup kopling longgar dan pemisahan perhatian.

  • Dengan pola pengkodean ini, kelas Anda hanya peduli dengan tugasnya sendiri dan, banyak lapisan aplikasi Anda, termasuk UI, tidak memiliki ketergantungan pada logika eksternal, seperti Entity Framework API, namun API eksternal tersebut dapat berinteraksi dengan kami. entitas.

Ada 2 cara (terhubung dan terputus) saat mempertahankan entitas dengan kerangka entitas. Kedua cara tersebut memiliki kepentingannya masing-masing. Dalam kasus skenario terhubung, perubahan dilacak oleh konteks tetapi dalam kasus skenario terputus kita perlu menginformasikan konteks tentang status entitas.

Skenario Terhubung

Skenario terhubung adalah ketika entitas diambil dari database dan dimodifikasi dalam konteks yang sama. Untuk skenario yang terhubung mari kita anggap kita memiliki layanan Windows dan kita melakukan beberapa operasi bisnis dengan entitas itu sehingga kita akan membuka konteks, memutar melalui semua entitas, melakukan operasi bisnis kita dan kemudian menyimpan perubahan dengan konteks yang sama dengan kita. dibuka di awal.

Mari kita lihat contoh berikut di mana siswa diambil dari database dan memperbarui nama depan siswa dan kemudian menyimpan perubahan ke database.

class Program {

   static void Main(string[] args) {

      using (var context = new MyContext()) {

         var studentList = context.Students.ToList();

         foreach (var stdnt in studentList) {
            stdnt.FirstMidName = "Edited " + stdnt.FirstMidName;
         }

         context.SaveChanges();

         //// Display all Students from the database

         var students = (from s in context.Students
            orderby s.FirstMidName select s).ToList<Student>();

         Console.WriteLine("Retrieve all Students from the database:");

         foreach (var stdnt in students) {
            string name = stdnt.FirstMidName + " " + stdnt.LastName;
            Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name);
         }

         Console.ReadKey();
      }
   }
}

Ketika kode di atas dikompilasi dan dijalankan, Anda akan menerima output berikut dan Anda akan melihat bahwa kata yang Diedit dilampirkan sebelum nama depan seperti yang ditunjukkan pada output berikut.

Retrieve all Students from the database: 
ID: 1, Name: Edited Edited Alain Bomer 
ID: 2, Name: Edited Edited Mark Upston

Skenario Terputus

Skenario terputus adalah ketika entitas diambil dari database dan dimodifikasi dalam konteks yang berbeda. Misalkan kita ingin menampilkan beberapa data dalam sebuah Presentation Layer dan kita menggunakan beberapa aplikasi n-tier, jadi akan lebih baik untuk membuka konteks, mengambil data dan terakhir menutup konteksnya. Karena di sini kami telah mengambil data dan menutup konteks, entitas yang telah kami ambil tidak lagi terlacak dan ini adalah skenario terputus.

Mari kita lihat kode berikut di mana entitas Mahasiswa baru yang terputus ditambahkan ke konteks menggunakan metode Tambah.

class Program {

   static void Main(string[] args) {

      var student = new Student {
         ID = 1001, 
         FirstMidName = "Wasim", 
         LastName = "Akram", 
         EnrollmentDate = DateTime.Parse( DateTime.Today.ToString())
      };

      using (var context = new MyContext()) {

         context.Students.Add(student);
         context.SaveChanges();

         //// Display all Students from the database

         var students = (from s in context.Students 
            orderby s.FirstMidName select s).ToList<Student>();

         Console.WriteLine("Retrieve all Students from the database:");

         foreach (var stdnt in students) {
            string name = stdnt.FirstMidName + " " + stdnt.LastName;
            Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name);
         }

         Console.ReadKey();
      }
   }
}

Ketika kode di atas dikompilasi dan dijalankan, Anda akan menerima output berikut.

Retrieve all Students from the database:
ID: 1, Name: Edited Edited Edited Alain Bomer
ID: 2, Name: Edited Edited Edited Mark Upston
ID: 3, Name: Wasim Akram

LINQ ke Entitas

Salah satu konsep terpenting untuk memahami LINQ ke Entitas adalah bahwa ini adalah bahasa deklaratif. Fokusnya adalah untuk menentukan informasi apa yang Anda butuhkan, bukan pada bagaimana mendapatkan informasi tersebut.

  • Ini berarti Anda dapat menghabiskan lebih banyak waktu untuk bekerja dengan data dan lebih sedikit waktu untuk mencoba mencari tahu kode dasar yang diperlukan untuk melakukan tugas-tugas seperti mengakses database.

  • Penting untuk dipahami bahwa bahasa deklaratif tidak benar-benar menghapus kontrol apa pun dari pengembang, tetapi membantu pengembang memusatkan perhatian pada hal yang penting.

LINQ ke Kata Kunci Penting Entitas

Penting untuk mengetahui kata kunci dasar yang digunakan untuk membuat kueri LINQ. Hanya ada beberapa kata kunci yang perlu diingat, tetapi Anda dapat menggabungkannya dengan berbagai cara untuk mendapatkan hasil tertentu. Daftar berikut berisi kata kunci dasar ini dan memberikan penjelasan sederhana tentang masing-masing kata kunci.

No Sr Kata Kunci & Deskripsi
1

Ascending

Menentukan bahwa operasi pengurutan berlangsung dari elemen terkecil (atau terendah) dari rentang hingga elemen tertinggi dari rentang. Ini biasanya merupakan pengaturan default. Misalnya, saat menjalankan pengurutan alfabet, pengurutan akan berada dalam rentang dari A hingga Z.

2

By

Menentukan bidang atau ekspresi yang digunakan untuk menerapkan pengelompokan. Bidang atau ekspresi mendefinisikan kunci yang digunakan untuk melakukan tugas pengelompokan.

3

Descending

Menentukan bahwa operasi pengurutan berlangsung dari elemen terbesar (atau tertinggi) dari rentang hingga elemen terendah dari rentang. Misalnya, saat menjalankan pengurutan alfabet, pengurutan akan berada dalam rentang dari Z hingga A.

4

Equals

Digunakan di antara klausa kiri dan kanan pernyataan gabungan untuk menggabungkan sumber data kontekstual primer ke sumber data kontekstual sekunder. Bidang atau ekspresi di sebelah kiri kata kunci sama dengan menentukan sumber data utama, sedangkan bidang atau ekspresi di sebelah kanan kata kunci sama dengan menentukan sumber data sekunder.

5

From

Menentukan sumber data yang digunakan untuk mendapatkan informasi yang diperlukan dan menentukan variabel rentang. Variabel ini memiliki tujuan yang sama dengan variabel yang digunakan untuk iterasi dalam satu loop.

6

Group

Mengatur keluaran ke dalam kelompok menggunakan nilai kunci yang Anda tentukan. Gunakan beberapa klausul grup untuk membuat beberapa tingkat organisasi keluaran. Urutan klausa grup menentukan kedalaman di mana nilai kunci tertentu muncul dalam urutan pengelompokan. Anda menggabungkan kata kunci ini dengan oleh untuk membuat konteks tertentu.

7

In

Digunakan dalam berbagai cara. Dalam kasus ini, kata kunci menentukan sumber database kontekstual yang digunakan untuk kueri. Saat bekerja dengan gabungan, kata kunci in digunakan untuk setiap sumber database kontekstual yang digunakan untuk gabungan.

8

Into

Menentukan pengidentifikasi yang bisa Anda gunakan sebagai referensi untuk klausa kueri LINQ seperti gabung, grup, dan pilih.

9

Join

Membuat satu sumber data dari dua sumber data terkait, seperti dalam penyiapan master / detail. Gabungan bisa menentukan gabungan dalam, grup, atau kiri-luar, dengan gabungan dalam sebagai default. Anda dapat membaca lebih lanjut tentang bergabung di msdn.microsoft.com

10

Let

Mendefinisikan variabel rentang yang dapat Anda gunakan untuk menyimpan hasil subekspresi dalam ekspresi kueri. Biasanya, variabel rentang digunakan untuk memberikan keluaran enumerasi tambahan atau untuk meningkatkan efisiensi kueri (sehingga tugas tertentu, seperti menemukan nilai huruf kecil dari sebuah string, tidak perlu dilakukan lebih dari satu kali).

11

On

Menentukan bidang atau ekspresi yang digunakan untuk mengimplementasikan gabungan. Bidang atau ekspresi menentukan elemen yang sama untuk kedua sumber data kontekstual.

12

Orderby

Membuat tata urutan kueri. Anda dapat menambahkan kata kunci ascending atau descending untuk mengontrol urutan pengurutan. Gunakan beberapa klausa orderby untuk membuat beberapa tingkat pengurutan. Urutan klausa orderby menentukan urutan penanganan ekspresi pengurutan, jadi menggunakan urutan yang berbeda akan menghasilkan keluaran yang berbeda.

13

Where

Mendefinisikan apa yang harus diambil LINQ dari sumber data. Anda menggunakan satu atau lebih ekspresi Boolean untuk menentukan secara spesifik apa yang akan diambil. Ekspresi Boolean dipisahkan satu sama lain menggunakan && (AND) dan || (OR) operator.

14

Select

Menentukan keluaran dari kueri LINQ dengan menentukan informasi apa yang akan dikembalikan. Pernyataan ini mendefinisikan tipe data dari elemen yang dikembalikan LINQ selama proses iterasi.

Proyeksi

Kueri proyeksi meningkatkan efisiensi aplikasi Anda, dengan hanya mengambil bidang tertentu dari database Anda.

  • Setelah Anda memiliki data, Anda mungkin ingin memproyeksikan atau memfilternya sesuai kebutuhan untuk membentuk data sebelum dikeluarkan.

  • Tugas utama ekspresi LINQ ke Entitas adalah mendapatkan data dan menyediakannya sebagai keluaran.

Bagian "Mengembangkan kueri LINQ ke Entitas" dari bab ini mendemonstrasikan teknik untuk melakukan tugas dasar ini.

Mari kita lihat kode berikut di mana daftar siswa akan diambil.

using (var context = new UniContextEntities()) {

   var studentList = from s in context.Students select s;

   foreach (var student in studentList) {
      string name = student.FirstMidName + " " + student.LastName;
      Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   }
}

Objek Tunggal

Untuk mengambil satu objek siswa, Anda dapat menggunakan metode enumerabel First () atau FirstOrDefault yang mengembalikan elemen pertama dari suatu urutan. Perbedaan antara First dan FirstOrDefault adalah First () akan memunculkan pengecualian, jika tidak ada data hasil untuk kriteria yang diberikan sedangkan FirstOrDefault () mengembalikan nilai default null, jika tidak ada data hasil. Dalam potongan kode di bawah ini, siswa pertama dari daftar akan diambil yang nama depannya adalah Ali.

using (var context = new UniContextEntities()) {

   var student = (from s in context.Students where s.FirstMidName 
      == "Ali" select s).FirstOrDefault<Student>();

   string name = student.FirstMidName + " " + student.LastName;
   Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
}

Anda juga bisa menggunakan Single () atau SingleOrDefault untuk mendapatkan satu objek siswa yang mengembalikan satu elemen spesifik dari suatu urutan. Dalam contoh berikut, satu siswa diambil dengan ID 2.

using (var context = new UniContextEntities()) {

   var student = (from s in context.Students where s.ID 
      == 2 select s).SingleOrDefault<Student>();
   string name = student.FirstMidName + " " + student.LastName;
	
   Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   Console.ReadKey();
}

Daftar Objek

Jika Anda ingin mengambil daftar siswa yang nama depannya adalah Ali maka Anda dapat menggunakan metode Enumerable ToList ().

using (var context = new UniContextEntities()) {

   var studentList = (from s in context.Students where s.FirstMidName 
      == "Ali" select s).ToList();

   foreach (var student in studentList) {
      string name = student.FirstMidName + " " + student.LastName;
      Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   }

   Console.ReadKey();
}

Memesan

Untuk mengambil data / daftar dalam urutan tertentu Anda dapat menggunakan kata kunci orderby. Pada kode berikut, potongan daftar siswa akan diambil dalam urutan menaik.

using (var context = new UniContextEntities()) {

   var studentList = (from s in context.Students orderby
      s.FirstMidName ascending select s).ToList();

   foreach (var student in studentList) {
      string name = student.FirstMidName + " " + student.LastName;
      Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   }

   Console.ReadKey();
}

Kueri Kerangka Kerja Entitas Standar Vs Proyeksi

Misalkan, Anda memiliki model Student yang berisi ID, FirstMidName, LastName, dan EnrollmentDate. Jika Anda ingin mengembalikan daftar Siswa, kueri standar akan mengembalikan semua bidang. Tetapi jika Anda hanya ingin mendapatkan daftar siswa yang berisi bidang ID, FirstMidName, dan LastName. Di sinilah Anda harus menggunakan kueri proyeksi. Berikut adalah contoh sederhana dari permintaan proyeksi.

using (var context = new UniContextEntities()) {

   var studentList = from s in context.Students
      orderby s.FirstMidName ascending
      where s.FirstMidName == "Ali"

   select new {s.ID, s.FirstMidName, s.LastName};

   foreach (var student in studentList) {
      string name = student.FirstMidName + " " + student.LastName;
      Console.WriteLine("ID : {0}, Name: {1}", student.ID, name);
   }

   Console.ReadKey();
}

Kueri proyeksi di atas mengecualikan bidang EnrollmentDate. Ini akan membuat aplikasi Anda lebih cepat.

Dalam Entity Framework 6.0, fitur baru diperkenalkan yang dikenal sebagai Logging SQL. Saat bekerja dengan Entity Framework, ia mengirimkan perintah atau kueri SQL yang setara ke database untuk melakukan operasi CRUD (Buat, Baca, Perbarui, dan Hapus).

  • Fitur Entity Framework ini adalah untuk menangkap kueri SQL setara yang dihasilkan oleh Entity Framework secara internal dan menyediakannya sebagai keluaran.

  • Sebelum Entity Framework 6, setiap kali ada kebutuhan untuk melacak kueri dan perintah database, pengembang tidak memiliki pilihan selain menggunakan beberapa utilitas pelacakan pihak ketiga atau alat pelacakan database.

  • Di Entity Framework 6, fitur baru ini menyediakan cara sederhana dengan mencatat semua operasi yang dilakukan oleh Entity Framework.

  • Semua aktivitas yang dilakukan oleh Entity Framework dicatat menggunakan DbContext.Database.Log.

Mari kita lihat kode berikut di mana siswa baru ditambahkan ke database.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         context.Database.Log = Console.Write;

         // Create a new student and save it

         context.Students.Add(new Student {
            FirstMidName = "Salman", 
            LastName = "Khan", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         });

         context.SaveChanges();
         Console.ReadKey();
      }
   }
}

Ketika kode di atas dijalankan, Anda akan menerima output berikut, yang sebenarnya merupakan log dari semua aktivitas yang dilakukan oleh EF pada kode di atas.

Opened connection at 10/28/2015 6:27:35 PM +05:00
Started transaction at 10/28/2015 6:27:35 PM +05:00
INSERT [dbo].[Student]([LastName], [FirstMidName], [EnrollmentDate])
VALUES (@0, @1, @2)
SELECT [ID]
FROM [dbo].[Student]
WHERE @@ROWCOUNT > 0 AND [ID] = scope_identity()
-- @0: 'Khan' (Type = String, Size = -1)
-- @1: 'Salman' (Type = String, Size = -1)
-- @2: '10/28/2015 12:00:00 AM' (Type = DateTime)
-- Executing at 10/28/2015 6:27:35 PM +05:00
-- Completed in 5 ms with result: SqlDataReader
Committed transaction at 10/28/2015 6:27:35 PM +05:00
Closed connection at 10/28/2015 6:27:35 PM +05:00

Ketika properti Log disetel, aktivitas berikut dicatat -

  • SQL untuk semua jenis perintah yang berbeda misalnya Kueri, termasuk penyisipan, pembaruan, dan penghapusan yang dihasilkan sebagai bagian dari SaveChanges

  • Parameters

  • Apakah perintah dijalankan secara asinkron atau tidak

  • Stempel waktu yang menunjukkan kapan perintah mulai dijalankan

  • Perintah berhasil diselesaikan atau gagal

  • Beberapa indikasi nilai hasil

  • Perkiraan waktu yang dibutuhkan untuk menjalankan perintah

Masuk ke Tempat Lain

Jika Anda sudah memiliki beberapa kerangka kerja logging dan itu mendefinisikan metode logging maka Anda juga bisa memasukkannya ke tempat lain.

Mari kita lihat contoh berikut di mana kita memiliki kelas MyLogger lainnya.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         context.Database.Log = s ⇒ MyLogger.Log("EFLoggingDemo", s);

         // Create a new student and save it

         context.Students.Add(new Student {
            FirstMidName = "Salman", 
            LastName = "Khan", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         });

         context.SaveChanges();
         Console.ReadKey();
      }
   }
}

public class MyLogger {

   public static void Log(string application, string message) {
      Console.WriteLine("Application: {0}, EF Message: {1} ",application, message);
   }
}

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Di Entity Framework 6.0, ada fitur baru lainnya yang disebut Interceptoratau Intersepsi. Kode intersepsi dibangun di sekitar konsepinterception interfaces. Misalnya, antarmuka IDbCommandInterceptor mendefinisikan metode yang dipanggil sebelum EF melakukan panggilan ke ExecuteNonQuery, ExecuteScalar, ExecuteReader, dan metode terkait.

  • Framework Entitas benar-benar dapat bersinar dengan menggunakan intersepsi. Dengan menggunakan pendekatan ini, Anda dapat menangkap lebih banyak informasi secara sementara tanpa harus mengacak-acak kode Anda.

  • Untuk menerapkan ini, Anda perlu membuat pencegat khusus Anda sendiri dan mendaftarkannya sesuai dengan itu.

  • Setelah kelas yang mengimplementasikan antarmuka IDbCommandInterceptor telah dibuat, kelas tersebut dapat didaftarkan dengan Entity Framework menggunakan kelas DbInterception.

  • Antarmuka IDbCommandInterceptor memiliki enam metode dan Anda perlu menerapkan semua metode ini. Berikut adalah implementasi dasar dari metode-metode tersebut.

Mari kita lihat kode berikut di mana antarmuka IDbCommandInterceptor diimplementasikan.

public class MyCommandInterceptor : IDbCommandInterceptor {

   public static void Log(string comm, string message) {
      Console.WriteLine("Intercepted: {0}, Command Text: {1} ", comm, message);
   }

   public void NonQueryExecuted(DbCommand command, 
      DbCommandInterceptionContext<int> interceptionContext) {
         Log("NonQueryExecuted: ", command.CommandText);
   }

   public void NonQueryExecuting(DbCommand command, 
      DbCommandInterceptionContext<int> interceptionContext) {
         Log("NonQueryExecuting: ", command.CommandText);
   }

   public void ReaderExecuted(DbCommand command, 
      DbCommandInterceptionContext<DbDataReader> interceptionContext) {
         Log("ReaderExecuted: ", command.CommandText);
   }

   public void ReaderExecuting(DbCommand command, 
      DbCommandInterceptionContext<DbDataReader> interceptionContext) {
         Log("ReaderExecuting: ", command.CommandText);
   }

   public void ScalarExecuted(DbCommand command, 
      DbCommandInterceptionContext<object> interceptionContext) {
         Log("ScalarExecuted: ", command.CommandText);
   }

   public void ScalarExecuting(DbCommand command, 
      DbCommandInterceptionContext<object> interceptionContext) {
         Log("ScalarExecuting: ", command.CommandText);
   }

}

Mendaftarkan Interceptors

Setelah kelas yang mengimplementasikan satu atau lebih antarmuka intersepsi telah dibuat, kelas tersebut dapat didaftarkan dengan EF menggunakan kelas DbInterception seperti yang ditunjukkan pada kode berikut.

DbInterception.Add(new MyCommandInterceptor());

Interceptors juga bisa didaftarkan di level app-domain menggunakan konfigurasi berbasis kode DbConfiguration seperti yang ditunjukkan pada kode berikut.

public class MyDBConfiguration : DbConfiguration {

   public MyDBConfiguration() {
      DbInterception.Add(new MyCommandInterceptor());
   }
}

Anda juga dapat mengkonfigurasi file konfigurasi interceptor menggunakan kode -

<entityFramework>
   <interceptors>
      <interceptor type = "EFInterceptDemo.MyCommandInterceptor, EFInterceptDemo"/>
   </interceptors>
</entityFramework>

Dukungan tipe spasial diperkenalkan di Entity Framework 5. Sekumpulan operator juga disertakan untuk memungkinkan kueri menganalisis data spasial. Misalnya, kueri dapat memfilter berdasarkan jarak antara dua lokasi geografis.

  • Kerangka Kerja Entitas akan memungkinkan tipe data spasial baru untuk diekspos sebagai properti di kelas Anda dan memetakannya ke kolom spasial di database Anda.

  • Anda juga akan dapat menulis kueri LINQ yang menggunakan operator spasial untuk memfilter, mengurutkan, dan mengelompokkan berdasarkan penghitungan spasial yang dilakukan dalam database.

Ada dua tipe data spasial utama -

  • Tipe data geografi menyimpan data ellipsoidal, misalnya koordinat lintang dan bujur GPS.

  • Tipe data geometri merepresentasikan sistem koordinat Euclidean (datar).

Mari kita lihat contoh lapangan Cricket berikut.

Step 1 - Buat proyek baru dari File → Baru → Opsi menu proyek.

Step 2 - Di panel kiri, pilih Aplikasi Konsol.

Step 3 - Klik kanan pada nama proyek dan pilih Kelola Paket NuGet…

Step 4 - Instal Entity Framework.

Step 5 - Tambahkan referensi ke perakitan System.Data.Entity dan juga tambahkan pernyataan System.Data.Spatial menggunakan untuk tipe data spasial.

Step 6 - Tambahkan kelas berikut di file Program.cs.

public class CricketGround {
   public int ID { get; set; }
   public string Name { get; set; }
   public DbGeography Location { get; set; }
}

Step 7 - Selain mendefinisikan entitas, Anda perlu mendefinisikan kelas yang berasal dari DbContext dan mengekspos properti DbSet <TEntity>.

Di Program.cs tambahkan definisi konteks.

public partial class CricketGroundContext : DbContext {
   public DbSet<CricketGround> CricketGrounds { get; set; }
}

Step 8 - Tambahkan kode berikut ke fungsi Utama, yang akan menambahkan dua objek CricketGround baru ke konteks.

class Program {

   static void Main(string[] args) {

      using (var context = new CricketGroundContext()) {

         context.CricketGrounds.Add(new CricketGround() {
            Name = "Shalimar Cricket Ground", 
            Location = DbGeography.FromText("POINT(-122.336106 47.605049)"), 
         });

         context.CricketGrounds.Add(new CricketGround() {
            Name = "Marghazar Stadium", Location = DbGeography
               .FromText("POINT(-122.335197 47.646711)"), 
         });

         context.SaveChanges();

         var myLocation = DbGeography.FromText("POINT(-122.296623 47.640405)");

         var cricketGround = (from cg in context.CricketGrounds
            orderby cg.Location.Distance(myLocation) select cg).FirstOrDefault();

         Console.WriteLine("The closest Cricket Ground to you is: {0}.", cricketGround.Name);
      }
   }
}

Properti spasial diinisialisasi dengan menggunakan metode DbGeography.FromText. Titik geografi yang direpresentasikan sebagai WellKnownText diteruskan ke metode dan kemudian menyimpan datanya. Setelah itu objek CricketGround akan diambil dimana lokasinya paling dekat dengan lokasi yang ditentukan.

Ketika kode di atas dijalankan, Anda akan menerima output berikut -

The closest Cricket Ground to you is: Marghazar Stadium

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Pewarisan memungkinkan untuk membuat model kompleks yang lebih mencerminkan bagaimana pengembang berpikir dan juga mengurangi pekerjaan yang diperlukan untuk berinteraksi dengan model tersebut. Pewarisan yang digunakan dengan entitas memiliki tujuan yang sama seperti pewarisan yang digunakan dengan kelas, sehingga pengembang sudah mengetahui dasar-dasar cara kerja fitur ini.

Mari kita lihat contoh berikut dan dengan membuat proyek aplikasi konsol baru.

Step 1 - Tambahkan Model Data Entitas ADO.NET dengan cara klik kanan pada nama proyek dan pilih Tambah → Item Baru…

Step 2 - Tambahkan satu entitas dan beri nama Person dengan mengikuti semua langkah yang disebutkan di bab Pendekatan Model Pertama.

Step 3 - Tambahkan beberapa properti skalar seperti yang ditunjukkan pada gambar berikut.

Step 4 - Kami akan menambahkan dua entitas lagi Student dan Teacher, yang akan mewarisi properti dari Person Table.

Step 5 - Sekarang tambahkan entitas Mahasiswa dan pilih Orang dari kotak kombo tipe Dasar seperti yang ditunjukkan pada gambar berikut.

Step 6 - Demikian pula menambahkan entitas Guru.

Step 7 - Sekarang tambahkan properti skalar EnrollmentDate ke entitas siswa dan properti HireDate ke entitas Guru.

Step 8 - Mari kita lanjutkan dan buat database.

Step 9 - Klik kanan pada permukaan desain dan pilih Generate Database from Model…

Step 10- Untuk membuat Database baru, klik New Connection… Dialog berikut akan terbuka. Klik OK.

Step 11- Klik Selesai. Ini akan menambahkan file * .edmx.sql dalam proyek. Anda dapat menjalankan skrip DDL di Visual Studio dengan membuka file .sql. Sekarang klik kanan dan pilih Execute.

Step 12 - Masuk ke server explorer Anda akan melihat bahwa database dibuat dengan tiga tabel yang ditentukan.

Step 13 - Anda juga dapat melihat bahwa kelas domain berikut juga dibuat secara otomatis.

public partial class Person {
   public int ID { get; set; }
   public string FirstMidName { get; set; }
   public string LastName { get; set; }
}

public partial class Student : Person {
   public System.DateTime EnrollmentDate { get; set; }
}

public partial class Teacher : Person {
   public System.DateTime HireDate { get; set; }
}

Berikut adalah kelas Konteks.

public partial class InheritanceModelContainer : DbContext {

   public InheritanceModelContainer() : 
      base("name = InheritanceModelContainer") {}

   protected override void OnModelCreating(DbModelBuilder modelBuilder) {
      throw new UnintentionalCodeFirstException();
   }

   public virtual DbSet<Person> People { get; set; }
}

Mari tambahkan beberapa Siswa dan Guru ke database dan kemudian mengambilnya dari database.

class Program {

   static void Main(string[] args) {

      using (var context = new InheritanceModelContainer()) {

         var student = new Student {
            FirstMidName = "Meredith", 
            LastName = "Alonso", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         };

         context.People.Add(student);

         var student1 = new Student {
            FirstMidName = "Arturo", 
            LastName = "Anand", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         };

         context.People.Add(student1);

         var techaer = new Teacher {
            FirstMidName = "Peggy", 
            LastName = "Justice", 
            HireDate = DateTime.Parse(DateTime.Today.ToString())
         };

         context.People.Add(techaer);

         var techaer1 = new Teacher {
            FirstMidName = "Yan", 
            LastName = "Li", 
            HireDate = DateTime.Parse(DateTime.Today.ToString())
         };

         context.People.Add(techaer1);
         context.SaveChanges();
      }
   }
}

Siswa dan guru ditambahkan ke dalam database. Untuk mengambil kembali siswa dan guru, fileOfType metode perlu digunakan, yang akan mengembalikan Siswa dan Guru terkait dengan departemen yang ditentukan.

Console.WriteLine("All students in database"); 
Console.WriteLine("");

foreach (var student in context.People.OfType<Student>()) {
   string name = student.FirstMidName + " " + student.LastName;
   Console.WriteLine("ID: {0}, Name: {1}, \tEnrollment Date {2} ", 
      student.ID, name, student.EnrollmentDate.ToString());
}

Console.WriteLine("");
Console.WriteLine("************************************************************ *****");
Console.WriteLine("");
Console.WriteLine("All teachers in database");
Console.WriteLine("");

foreach (var teacher in context.People.OfType<Teacher>()) {
   string name = teacher.FirstMidName + " " + teacher.LastName;
   Console.WriteLine("ID: {0}, Name: {1}, \tHireDate {2} ", 
      teacher.ID, name, teacher.HireDate.ToString()); 
}

Console.WriteLine("");
Console.WriteLine("************************************************************ *****");
Console.ReadKey();

Dalam kueri pertama, ketika Anda menggunakan OfType <Student> () maka Anda tidak akan dapat mengakses HireDate karena properti HireDate adalah bagian dari Entitas Guru dan demikian pula properti EnrollmentDate tidak akan dapat diakses ketika Anda menggunakan OfType <Teacher> ()

Ketika kode di atas dijalankan, Anda akan menerima output berikut -

All students in database
ID: 1, Name: Meredith Alonso,   Enrollment Date 10/30/2015 12:00:00 AM
ID: 2, Name: Arturo Anand,      Enrollment Date 10/30/2015 12:00:00 AM
*****************************************************************  
All teachers in database
ID: 3, Name: Peggy Justice,     HireDate 10/30/2015 12:00:00 AM
ID: 4, Name: Yan Li,    HireDate 10/30/2015 12:00:00 AM
*****************************************************************

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Di Entity Framework 5 dan versi sebelumnya dari Entity Framework, kode tersebut dipisahkan antara pustaka inti (terutama System.Data.Entity.dll) yang dikirim sebagai bagian dari .NET Framework, dan pustaka tambahan (terutama EntityFramework.dll) didistribusikan dan dikirim menggunakan NuGet seperti yang ditunjukkan pada diagram berikut.

Dalam Entity Framework 6, API inti yang sebelumnya merupakan bagian dari kerangka .NET juga dikirimkan dan didistribusikan sebagai bagian dari paket NuGet.

Ini diperlukan untuk memungkinkan Entity Framework dibuat open source. Namun, sebagai konsekuensinya, aplikasi perlu dibangun kembali setiap kali ada kebutuhan untuk memigrasi atau meningkatkan aplikasi Anda dari versi lama Entity Framework ke EF 6.

Proses migrasi sangat mudah jika aplikasi Anda menggunakan DbContext, yang dikirimkan dalam EF 4.1 dan yang lebih baru. Tetapi jika aplikasi Anda adalah ObjectContext, maka dibutuhkan sedikit lebih banyak pekerjaan.

Mari kita lihat langkah-langkah berikut yang perlu Anda lakukan untuk meningkatkan aplikasi yang ada ke EF6.

Step 1 - Langkah pertama adalah menargetkan .NET Framework 4.5.2 dan kemudian klik kanan pada proyek Anda dan pilih properti.

Step 2 - Klik kanan pada proyek Anda lagi dan pilih Kelola Paket NuGet ...

Step 3- Di bawah tab Online pilih EntityFramework dan klik Install. Pastikan bahwa referensi perakitan untuk System.Data.Entity.dll dihapus.

Ketika Anda menginstal paket EF6 NuGet, itu akan secara otomatis menghapus semua referensi ke System.Data.Entity dari proyek Anda untuk Anda.

Step 4 - Jika Anda memiliki model yang dibuat dengan EF Designer, Anda juga perlu memperbarui templat pembuatan kode untuk menghasilkan kode yang kompatibel dengan EF6.

Step 5 - Di Penjelajah Solusi di bawah file edmx Anda, hapus template pembuatan kode yang ada yang biasanya akan diberi nama <edmx_file_name> .tt dan <edmx_file_name> .Context.tt.

Step 6 - Buka model Anda di EF Designer, klik kanan pada permukaan desain dan pilih Tambahkan Item Pembuatan Kode ...

Step 7 - Tambahkan templat pembuatan kode EF 6.x yang sesuai.

Ini juga akan menghasilkan kode yang kompatibel dengan EF6 secara otomatis.

Jika aplikasi Anda menggunakan EF 4.1 atau yang lebih baru, Anda tidak perlu mengubah apa pun di kodenya, karena namespace untuk DbContext dan tipe Code First tidak berubah.

Tetapi jika aplikasi Anda menggunakan versi Entity Framework yang lebih lama, maka jenis seperti ObjectContext yang sebelumnya ada di System.Data.Entity.dll telah dipindahkan ke namespace baru.

Step 8 - Anda perlu memperbarui petunjuk penggunaan atau Impor Anda untuk membangun melawan EF6.

Aturan umum untuk perubahan namespace adalah bahwa semua jenis di System.Data. * Dipindahkan ke System.Data.Entity.Core. *. Berikut adalah beberapa di antaranya -

  • System.Data.EntityException ⇒ System.Data.Entity.Core.EntityException
  • System.Data.Objects.ObjectContext ⇒ System.Data.Entity.Core.Objects.ObjectContext;
  • System.Data.Objects.DataClasses.RelationshipManager ⇒ System.Data.Entity.Core.Objects.DataClasses.RelationshipManager;

Beberapa tipe berada di ruang nama Inti karena tidak digunakan secara langsung untuk sebagian besar aplikasi berbasis DbContext.

  • System.Data.EntityState ⇒ System.Data.Entity.EntityState
  • System.Data.Objects.DataClasses.EdmFunctionAttribute ⇒ System.Data.Entity.DbFunctionAttribute

Proyek Entity Framework Anda yang sudah ada akan berfungsi di Entity Framework 6.0 tanpa perubahan besar apa pun.

Eager loading adalah proses di mana kueri untuk satu jenis entitas juga memuat entitas terkait sebagai bagian dari kueri. Eager loading dicapai dengan menggunakan fileInclude method.

Artinya meminta data terkait dikembalikan bersama dengan hasil query dari database. Hanya ada satu koneksi yang dibuat ke sumber data, sejumlah besar data dikembalikan di kueri awal.

Misalnya, saat menanyakan siswa, harap memuat pendaftaran mereka. Para siswa dan pendaftaran mereka akan diambil dalam satu kueri.

Mari kita lihat contoh berikut di mana semua siswa dengan pendaftaran masing-masing diambil dari database dengan menggunakan eager loading.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {
         // Load all students and related enrollments
         var students = context.Students
            .Include(s ⇒ s.Enrollments).ToList();
			
         foreach (var student in students) {
            string name = student.FirstMidName + " " + student.LastName;
            Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);
				
            foreach (var enrollment in student.Enrollments) {
               Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", 
                  enrollment.EnrollmentID, enrollment.CourseID);
            }
         }

         Console.ReadKey();
      }
   }
}

Ketika kode di atas dikompilasi dan dijalankan, Anda akan menerima output berikut.

ID: 1, Name: Ali Alexander
       Enrollment ID: 1, Course ID: 1050
       Enrollment ID: 2, Course ID: 4022
       Enrollment ID: 3, Course ID: 4041
ID: 2, Name: Meredith Alonso
       Enrollment ID: 4, Course ID: 1045
       Enrollment ID: 5, Course ID: 3141
       Enrollment ID: 6, Course ID: 2021
ID: 3, Name: Arturo Anand
       Enrollment ID: 7, Course ID: 1050
ID: 4, Name: Gytis Barzdukas
       Enrollment ID: 8, Course ID: 1050
       Enrollment ID: 9, Course ID: 4022

Di bawah ini adalah beberapa bentuk permintaan eager loading yang dapat digunakan.

// Load one Student and its related enrollments

var student1 = context.Students
   .Where(s ⇒ s.FirstMidName == "Ali")
   .Include(s ⇒ s.Enrollments).FirstOrDefault();

// Load all Students and related enrollments
// using a string to specify the relationship

var studentList = context.Students
   .Include("Enrollments").ToList();

// Load one Student and its related enrollments
// using a string to specify the relationship

var student = context.Students
   .Where(s ⇒ s.FirstMidName == "Salman")
   .Include("Enrollments").FirstOrDefault();

Beberapa Tingkat

Dimungkinkan juga untuk memuat banyak level entitas terkait. Kueri berikut menunjukkan contoh Siswa, Pendaftaran, dan Kursus.

// Load all Students, all related enrollments, and all related courses

var studentList = context.Students
   .Include(s ⇒ s.Enrollments.Select(c ⇒ c.Course)).ToList();

// Load all Students, all related enrollments, and all related courses
// using a string to specify the relationships

var students = context.Students
   .Include("Enrollments.Course").ToList();

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Lazy loading adalah proses dimana entitas atau kumpulan entitas secara otomatis dimuat dari database saat pertama kali properti yang merujuk ke entitas / entitas tersebut diakses. Pemuatan lambat berarti menunda pemuatan data terkait, hingga Anda secara khusus memintanya.

  • Saat menggunakan tipe entitas POCO, pemuatan lambat dicapai dengan membuat instance dari tipe proxy turunan dan kemudian mengganti properti virtual untuk menambahkan hook pemuatan.

  • Lazy loading adalah defaultnya.

  • Jika Anda meninggalkan konfigurasi default, dan tidak secara eksplisit memberi tahu Entity Framework dalam kueri Anda bahwa Anda menginginkan sesuatu selain pemuatan lambat, maka pemuatan lambat adalah yang akan Anda dapatkan.

  • Misalnya, saat menggunakan kelas entitas Mahasiswa, Pendaftaran terkait akan dimuat saat pertama kali properti navigasi Pendaftaran diakses.

  • Properti navigasi harus didefinisikan sebagai publik, virtual. Konteks akanNOT melakukan lazy loading jika properti tidak didefinisikan sebagai virtual.

Berikut adalah kelas Mahasiswa yang berisi properti navigasi Pendaftaran.

public partial class Student {

   public Student() {
      this.Enrollments = new HashSet<Enrollment>();
   }
	
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public System.DateTime EnrollmentDate { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Mari kita lihat contoh sederhana di mana daftar siswa dimuat dari database terlebih dahulu dan kemudian itu akan memuat pendaftaran siswa tertentu kapan pun Anda membutuhkannya.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         //Loading students only
         IList<Student> students = context.Students.ToList<Student>();

         foreach (var student in students) {

            string name = student.FirstMidName + " " + student.LastName;
            Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);
	
            foreach (var enrollment in student.Enrollments) {
               Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", 
                  enrollment.EnrollmentID, enrollment.CourseID);
            }
         }

         Console.ReadKey();
      }
   }
}

Ketika kode di atas dikompilasi dan dijalankan, Anda akan menerima output berikut.

ID: 1, Name: Ali Alexander
       Enrollment ID: 1, Course ID: 1050
       Enrollment ID: 2, Course ID: 4022
       Enrollment ID: 3, Course ID: 4041
ID: 2, Name: Meredith Alonso
       Enrollment ID: 4, Course ID: 1045
       Enrollment ID: 5, Course ID: 3141
       Enrollment ID: 6, Course ID: 2021
ID: 3, Name: Arturo Anand
       Enrollment ID: 7, Course ID: 1050
ID: 4, Name: Gytis Barzdukas
       Enrollment ID: 8, Course ID: 1050
       Enrollment ID: 9, Course ID: 4022
ID: 5, Name: Yan Li
       Enrollment ID: 10, Course ID: 4041
ID: 6, Name: Peggy Justice
       Enrollment ID: 11, Course ID: 1045
ID: 7, Name: Laura Norman
       Enrollment ID: 12, Course ID: 3141

Matikan Lazy Loading

Pemuatan lambat dan serialisasi tidak cocok, dan jika Anda tidak berhati-hati, Anda dapat membuat kueri untuk seluruh database Anda hanya karena pemuatan lambat diaktifkan. Merupakan praktik yang baik untuk menonaktifkan pemuatan lambat sebelum Anda membuat serial entitas.

Mematikan untuk Properti Navigasi Tertentu

Pemuatan lambat dari koleksi Pendaftaran dapat dimatikan dengan menjadikan properti Pendaftaran non-virtual seperti yang diperlihatkan dalam contoh berikut.

public partial class Student { 

   public Student() { 
      this.Enrollments = new HashSet<Enrollment>(); 
   }
	
   public int ID { get; set; } 
   public string LastName { get; set; } 
   public string FirstMidName { get; set; } 
   public System.DateTime EnrollmentDate { get; set; }
   public ICollection<Enrollment> Enrollments { get; set; } 
}

Matikan untuk Semua Entitas

Pemuatan lambat dapat dimatikan untuk semua entitas dalam konteks dengan menyetel bendera pada properti Konfigurasi menjadi salah seperti yang ditunjukkan pada contoh berikut.

public partial class UniContextEntities : DbContext { 

   public UniContextEntities(): base("name=UniContextEntities") {
      this.Configuration.LazyLoadingEnabled = false;
   }
	
   protected override void OnModelCreating(DbModelBuilder modelBuilder) { 
      throw new UnintentionalCodeFirstException(); 
   } 
}

Setelah mematikan pemuatan lambat, sekarang ketika Anda menjalankan contoh di atas lagi Anda akan melihat bahwa Pendaftaran tidak dimuat dan hanya data siswa yang diambil.

ID: 1, Name: Ali Alexander
ID: 2, Name: Meredith Alons
ID: 3, Name: Arturo Anand
ID: 4, Name: Gytis Barzduka
ID: 5, Name: Yan Li
ID: 6, Name: Peggy Justice
ID: 7, Name: Laura Norman
ID: 8, Name: Nino Olivetto

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Saat Anda menonaktifkan pemuatan lambat, pemuatan lambat entitas terkait masih mungkin dilakukan, tetapi harus dilakukan dengan panggilan eksplisit.

  • Tidak seperti lazy loading, tidak ada ambiguitas atau kemungkinan kebingungan terkait kapan kueri dijalankan.

  • Untuk melakukannya, Anda menggunakan metode Muat pada entri entitas terkait.

  • Untuk hubungan one-to-many, panggil metode Load on Collection.

  • Dan untuk hubungan satu-ke-satu, panggil metode Muat di Referensi.

Mari kita lihat contoh berikut di mana lazy loading dinonaktifkan dan kemudian siswa yang nama depannya adalah Ali diambil.

Informasi siswa kemudian ditulis di konsol. Jika Anda melihat kodenya, informasi pendaftaran juga tertulis tetapi entitas Pendaftaran belum dimuat sehingga foreach loop tidak akan dijalankan.

Setelah entitas Pendaftaran dimuat secara eksplisit sekarang informasi siswa dan informasi pendaftaran akan ditulis di jendela konsol.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         context.Configuration.LazyLoadingEnabled = false;

         var student = (from s in context.Students where s.FirstMidName == 
            "Ali" select s).FirstOrDefault<Student>();

         string name = student.FirstMidName + " " + student.LastName;
         Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", 
               enrollment.EnrollmentID, enrollment.CourseID);
         }

         Console.WriteLine();
         Console.WriteLine("Explicitly loaded Enrollments");
         Console.WriteLine();

         context.Entry(student).Collection(s ⇒ s.Enrollments).Load();
         Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", 
               enrollment.EnrollmentID, enrollment.CourseID);
         }

         Console.ReadKey();
      }
   }
}

Ketika contoh di atas dijalankan, Anda akan menerima output berikut. Pertama hanya informasi siswa yang ditampilkan dan setelah secara eksplisit memuat entitas pendaftaran, baik siswa dan informasi pendaftaran terkaitnya akan ditampilkan.

ID: 1, Name: Ali Alexander
Explicitly loaded Enrollments
ID: 1, Name: Ali Alexander
       Enrollment ID: 1, Course ID: 1050
       Enrollment ID: 2, Course ID: 4022
       Enrollment ID: 3, Course ID: 4041

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Dalam bab ini mari kita belajar tentang teknik validasi yang dapat digunakan dalam ADO.NET Entity Framework untuk memvalidasi data model. Entity Framework menyediakan berbagai macam fitur validasi yang dapat diimplementasikan ke antarmuka pengguna untuk validasi sisi klien atau dapat digunakan untuk validasi sisi server.

  • Dalam Entity Framework, validasi data adalah bagian dari solusi untuk menangkap data buruk dalam aplikasi.

  • Entity Framework memvalidasi semua data sebelum ditulis ke database secara default, menggunakan berbagai metode validasi data.

  • Namun, Entity Framework muncul setelah validasi data antarmuka pengguna. Jadi dalam hal ini diperlukan validasi entitas untuk menangani pengecualian apa pun yang dilontarkan EF dan menampilkan pesan umum.

  • Ada beberapa teknik validasi data untuk meningkatkan pemeriksaan kesalahan Anda dan cara meneruskan pesan kesalahan kembali ke pengguna.

DbContext memiliki metode Overridable yang disebut ValidateEntity. Saat Anda memanggil SaveChanges, Entity Framework akan memanggil metode ini untuk setiap entitas di cache yang statusnya tidak berubah. Anda dapat meletakkan logika validasi langsung di sini seperti yang ditunjukkan pada contoh berikut untuk Entitas Mahasiswa.

public partial class UniContextEntities : DbContext {

   protected override System.Data.Entity.Validation
      .DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, 
      System.Collections.Generic.IDictionary<object, object> items) {

         if (entityEntry.Entity is Student) {

            if (entityEntry.CurrentValues.GetValue<string>("FirstMidName") == "") {

               var list = new List<System.Data.Entity
                  .Validation.DbValidationError>();

               list.Add(new System.Data.Entity.Validation
                  .DbValidationError("FirstMidName", "FirstMidName is required"));

               return new System.Data.Entity.Validation
                  .DbEntityValidationResult(entityEntry, list);
            }
         }

         if (entityEntry.CurrentValues.GetValue<string>("LastName") == "") {

            var list = new List<System.Data.Entity
               .Validation.DbValidationError>();

            list.Add(new System.Data.Entity.Validation
               .DbValidationError("LastName", "LastName is required"));

            return new System.Data.Entity.Validation
               .DbEntityValidationResult(entityEntry, list);
         }

         return base.ValidateEntity(entityEntry, items);
   }
}

Dalam metode ValidateEntity di atas, properti FirstMidName dan LastName entitas siswa diperiksa jika salah satu properti ini memiliki string kosong, maka itu akan mengembalikan pesan kesalahan.

Mari kita lihat contoh sederhana di mana siswa baru dibuat, tetapi FirstMidName siswa adalah string kosong seperti yang ditunjukkan pada kode berikut.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         Console.WriteLine("Adding new Student to the database");
         Console.WriteLine();

         try {

            context.Students.Add(new Student() {
               FirstMidName = "",
               LastName = "Upston"
            });

            context.SaveChanges();
         } catch (DbEntityValidationException dbValidationEx) {

            foreach (DbEntityValidationResult entityErr in 
               dbValidationEx.EntityValidationErrors) {

               foreach (DbValidationError error in entityErr.ValidationErrors) {
                  Console.WriteLine("Error: {0}",error.ErrorMessage);
               }
            }
         }

         Console.ReadKey();
      }
   }
}

Ketika contoh di atas dikompilasi dan dijalankan, Anda akan menerima pesan kesalahan berikut di jendela konsol.

Adding new Student to the database  
Error: FirstMidName is required

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Kerangka Kerja Entitas menyediakan kemampuan untuk melacak perubahan yang dibuat pada entitas dan relasinya, sehingga pembaruan yang benar dibuat pada database saat metode konteks SaveChanges dipanggil. Ini adalah fitur utama dari Entity Framework.

  • Pelacakan Perubahan melacak perubahan sambil menambahkan catatan baru ke kumpulan entitas, mengubah atau menghapus entitas yang ada.

  • Kemudian semua perubahan disimpan oleh level DbContext.

  • Perubahan trek ini hilang jika tidak disimpan sebelum objek DbContext dimusnahkan.

  • Kelas DbChangeTracker memberi Anda semua informasi tentang entitas saat ini yang dilacak oleh konteks.

  • Untuk melacak entitas apa pun dengan konteksnya, entitas tersebut harus memiliki properti kunci utama.

Di Entity Framework, pelacakan perubahan diaktifkan secara default. Anda juga dapat menonaktifkan pelacakan perubahan dengan menyetel properti AutoDetectChangesEnabled dari DbContext ke false. Jika properti ini disetel ke true maka Entity Framework mempertahankan status entitas.

using (var context = new UniContextEntities()) {
   context.Configuration.AutoDetectChangesEnabled = true;
}

Mari kita lihat contoh berikut di mana siswa dan pendaftaran mereka diambil dari database.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         context.Configuration.AutoDetectChangesEnabled = true;
         Console.WriteLine("Retrieve Student");

         var student = (from s in context.Students where s.FirstMidName == 
            "Ali" select s).FirstOrDefault<Student>();

         string name = student.FirstMidName + " " + student.LastName;
         Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);
         Console.WriteLine();
         Console.WriteLine("Retrieve all related enrollments");

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", 
               enrollment.EnrollmentID, enrollment.CourseID);
         }

         Console.WriteLine();

         Console.WriteLine("Context tracking changes of {0} entity.", 
            context.ChangeTracker.Entries().Count());

         var entries = context.ChangeTracker.Entries();

         foreach (var entry in entries) {
            Console.WriteLine("Entity Name: {0}", entry.Entity.GetType().Name);
            Console.WriteLine("Status: {0}", entry.State);
         }

         Console.ReadKey();
      }
   }
}

Ketika contoh di atas dikompilasi dan dijalankan, Anda akan menerima output berikut.

Retrieve Student 
ID: 1, Name: Ali Alexander
Retrieve all related enrollments
       Enrollment ID: 1, Course ID: 1050
       Enrollment ID: 2, Course ID: 4022
       Enrollment ID: 3, Course ID: 4041
Context tracking changes of 4 entity.
Entity Name: Student
Status: Unchanged
Entity Name: Enrollment
Status: Unchanged
Entity Name: Enrollment
Status: Unchanged
Entity Name: Enrollment
Status: Unchanged

Anda dapat melihat bahwa semua data hanya diambil dari database, itulah sebabnya status tidak berubah untuk semua entitas.

Sekarang mari kita lihat contoh sederhana lainnya di mana kita akan menambahkan satu pendaftaran lagi dan menghapus satu siswa dari database. Berikut adalah kode di mana pendaftaran baru ditambahkan dan satu siswa dihapus.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         context.Configuration.AutoDetectChangesEnabled = true;

         Enrollment enr = new Enrollment() { 
            StudentID = 1, CourseID = 3141 
         };

         Console.WriteLine("Adding New Enrollment");
         context.Enrollments.Add(enr);
         Console.WriteLine("Delete Student");

         var student = (from s in context.Students where s.ID == 
            23 select s).SingleOrDefault<Student>();

         context.Students.Remove(student);
         Console.WriteLine("");

         Console.WriteLine("Context tracking changes of {0} entity.", 
            context.ChangeTracker.Entries().Count());
         var entries = context.ChangeTracker.Entries();

         foreach (var entry in entries) {
            Console.WriteLine("Entity Name: {0}", entry.Entity.GetType().Name);
            Console.WriteLine("Status: {0}", entry.State);
         }

         Console.ReadKey();
      }
   }
}

Ketika contoh di atas dikompilasi dan dijalankan, Anda akan menerima output berikut.

Adding New Enrollment
Delete Student
Context tracking changes of 2 entity.
Entity Name: Enrollment
Status: Added
Entity Name: Student
Status: Deleted

Anda sekarang dapat melihat bahwa status entitas pendaftaran diatur ke ditambahkan, dan status entitas siswa dihapus, karena pendaftaran baru telah ditambahkan dan satu siswa dihapus dari database.

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Dalam Entity Framework, Colored Entity terutama tentang mengubah warna entitas di desainer sehingga mudah bagi pengembang untuk mengidentifikasi grup terkait entitas di desainer Visual Studio. Fitur ini pertama kali diperkenalkan di Entity Framework 5.0.

  • Fitur ini tidak ada hubungannya dengan aspek kinerja.

  • Jika Anda memiliki project berskala besar dan banyak entitas dalam satu file edmx, maka fitur ini sangat membantu untuk memisahkan entitas Anda dalam modul yang berbeda.

Jika Anda bekerja dengan file edmx dan Anda telah membukanya di desainer, untuk mengubah warna, pilih entitas di jendela desain. Kemudian klik kanan dan pilih Properties.

Di jendela Properties, pilih properti Fill Color.

Tentukan warna menggunakan nama warna yang valid, misalnya, Hijau atau RGB yang valid (255, 128, 128) atau Anda juga dapat memilih dari pemilih warna.

Untuk mengubah warna beberapa entitas sekaligus, pilih beberapa entitas dan ubah Warna Isi untuk semuanya menggunakan jendela properti.

Anda juga dapat mengubah format properti dengan memilih salah satu opsi berikut -

  • Nama tampilan
  • Nama dan Jenis Tampilan

Secara default, opsi nama tampilan dipilih. Untuk mengubah format properti, klik kanan pada jendela desainer.

Pilih Format Properti Skalar → Nama dan Jenis Tampilan.

Sekarang Anda dapat melihat bahwa tipe juga ditampilkan bersama dengan namanya.

Kerangka Entitas menyediakan tiga pendekatan untuk membuat model entitas dan masing-masing memiliki pro dan kontra sendiri.

  • Kode Pertama
  • Database Pertama
  • Model Pertama

Dalam bab ini, kami akan menjelaskan secara singkat pendekatan pertama kode. Beberapa pengembang lebih suka bekerja dengan Desainer dalam Kode sementara yang lain lebih suka bekerja dengan kode mereka. Untuk pengembang tersebut, Entity Framework memiliki alur kerja pemodelan yang disebut sebagai Kode Pertama.

  • Alur kerja pemodelan Code First menargetkan database yang tidak ada dan Code First akan membuatnya.

  • Ini juga dapat digunakan jika Anda memiliki database kosong dan kemudian Code First akan menambahkan tabel baru ke dalamnya.

  • Code First memungkinkan Anda untuk menentukan model Anda menggunakan kelas C # atau VB.Net.

  • Konfigurasi tambahan secara opsional dapat dilakukan menggunakan atribut pada kelas dan properti Anda atau dengan menggunakan API yang lancar.

Mengapa Kode Dulu?

  • Code First benar-benar terdiri dari satu set potongan puzzle. Pertama adalah kelas domain Anda.

  • Kelas domain tidak ada hubungannya dengan Entity Framework. Mereka hanyalah item dari domain bisnis Anda.

  • Entity Framework, kemudian, memiliki konteks yang mengelola interaksi antara kelas-kelas tersebut dan database Anda.

  • Konteksnya tidak spesifik untuk Code First. Ini adalah fitur Entity Framework.

  • Code First menambahkan pembuat model yang memeriksa kelas Anda yang dikelola konteks, lalu menggunakan sekumpulan aturan atau konvensi untuk menentukan bagaimana kelas dan hubungan tersebut mendeskripsikan model, dan bagaimana model tersebut harus dipetakan ke database Anda.

  • Semua ini terjadi saat runtime. Anda tidak akan pernah melihat model ini, hanya ada di memori.

  • Code First juga memiliki kemampuan untuk menggunakan model itu untuk membuat database jika Anda mau.

  • Itu juga dapat memperbarui database jika model berubah, menggunakan fitur yang disebut Migrasi Pertama Kode.

Pengaturan Lingkungan

Untuk mulai bekerja dengan pendekatan EF Code First, Anda memerlukan alat berikut untuk diinstal pada sistem Anda.

  • Visual Studio 2013 (.net framework 4.5.2) atau versi yang lebih baru.
  • MS SQL Server 2012 atau yang lebih baru.
  • Kerangka Kerja Entitas melalui Paket NuGet.

Instal EF melalui Paket NuGet

Step 1 - Pertama, buat aplikasi konsol dari File → New → Project…

Step 2 - Pilih Windows dari panel kiri dan Aplikasi Konsol dari panel template.

Step 3 - Masukkan EFCodeFirstDemo sebagai nama dan pilih OK.

Step 4 - Klik kanan pada proyek Anda di penjelajah solusi dan pilih Kelola Paket NuGet…

Ini akan membuka NuGet Package Manager, dan mencari EntityFramework. Ini akan mencari semua paket yang terkait dengan Entity Framework.

Step 5- Pilih EntityFramework dan klik Instal. Atau dari menu Tools klik NuGet Package Manager dan kemudian klik Package Manager Console. Di jendela Package Manager Console, masukkan perintah berikut: Install-Package EntityFramework.

Ketika penginstalan selesai, Anda akan melihat pesan berikut di jendela keluaran "Berhasil menginstal 'EntityFramework 6.1.2' ke EFCodeFirstDemo".

Setelah instalasi, EntityFramework.dll akan disertakan dalam proyek Anda, seperti yang ditunjukkan pada gambar berikut.

Sekarang Anda siap untuk mulai mengerjakan pendekatan Code First.

Mari kita definisikan model yang sangat sederhana menggunakan kelas. Kami hanya mendefinisikannya di file Program.cs tetapi dalam aplikasi dunia nyata Anda akan membagi kelas Anda menjadi file terpisah dan berpotensi menjadi proyek terpisah. Berikut model data yang akan kita buat menggunakan pendekatan Code First.

Buat Model

Tambahkan tiga kelas berikut dalam file Program.cs menggunakan kode berikut untuk kelas Siswa.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}
  • Properti ID akan menjadi kolom kunci utama dari tabel database yang sesuai dengan kelas ini.

  • Properti Pendaftaran adalah properti navigasi. Properti navigasi menyimpan entitas lain yang terkait dengan entitas ini.

  • Dalam kasus ini, properti Pendaftaran entitas Mahasiswa akan menampung semua entitas Pendaftaran yang terkait dengan entitas Mahasiswa tersebut.

  • Properti navigasi biasanya didefinisikan sebagai virtual sehingga dapat memanfaatkan fungsionalitas Entity Framework tertentu seperti pemuatan lambat.

  • Jika properti navigasi bisa menampung banyak entitas (seperti dalam hubungan banyak-ke-banyak atau satu-tomany), tipenya harus berupa daftar di mana entri dapat ditambahkan, dihapus, dan diperbarui, seperti ICollection.

Berikut adalah implementasi untuk kelas Course.

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Properti Pendaftaran adalah properti navigasi. Entitas Kursus dapat dikaitkan dengan sejumlah entitas Pendaftaran.

Berikut implementasi untuk Enrollment class dan enum.

public enum Grade {
   A, B, C, D, F
}

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }
}
  • Properti EnrollmentID akan menjadi kunci utama.

  • Properti Grade adalah enum. Tanda tanya setelah deklarasi tipe Grade menunjukkan bahwa properti Grade nullable.

  • Nilai yang nol berbeda dengan nilai nol. Null berarti nilai belum diketahui atau belum ditetapkan.

  • Properti StudentID dan CourseID adalah kunci asing, dan properti navigasi terkait adalah Student dan Course.

  • Entitas Pendaftaran dikaitkan dengan satu Siswa dan satu entitas Kursus, sehingga properti hanya dapat menampung satu entitas Siswa dan Kursus.

Buat Konteks Database

Kelas utama yang mengoordinasikan fungsionalitas Entity Framework untuk model data tertentu adalah kelas konteks database yang memungkinkan untuk melakukan kueri dan menyimpan data. Anda dapat membuat kelas ini dengan mengambil dari kelas DbContext dan mengekspos DbSet yang diketik untuk setiap kelas dalam model kami. Berikut adalah implementasi pada kelas MyContext yang diturunkan dari kelas DbContext.

public class MyContext : DbContext {
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

Berikut kode lengkap di file Program.cs.

using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCodeFirstDemo {

   class Program {
      static void Main(string[] args) {}
   }

   public enum Grade {
      A, B, C, D, F
   }

   public class Enrollment {
      public int EnrollmentID { get; set; }
      public int CourseID { get; set; }
      public int StudentID { get; set; }
      public Grade? Grade { get; set; }
		
      public virtual Course Course { get; set; }
      public virtual Student Student { get; set; }
   }

   public class Student {
      public int ID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
      public DateTime EnrollmentDate { get; set; }
		
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }

   public class Course {
      public int CourseID { get; set; }
      public string Title { get; set; }
      public int Credits { get; set; }
		
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }

   public class MyContext : DbContext {
      public virtual DbSet<Course> Courses { get; set; }
      public virtual DbSet<Enrollment> Enrollments { get; set; }
      public virtual DbSet<Student> Students { get; set; }
   }

}

Kode di atas adalah semua yang kita butuhkan untuk mulai menyimpan dan mengambil data. Mari tambahkan beberapa data dan kemudian ambil kembali. Berikut adalah kode dalam metode utama.

static void Main(string[] args) {

   using (var context = new MyContext()) {
      // Create and save a new Students
      Console.WriteLine("Adding new students");

      var student = new Student {
         FirstMidName = "Alain", LastName = "Bomer", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
      };

      context.Students.Add(student);
		
      var student1 = new Student {
         FirstMidName = "Mark", LastName = "Upston", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
      };

      context.Students.Add(student1);
      context.SaveChanges();

      // Display all Students from the database
      var students = (from s in context.Students 
         orderby s.FirstMidName select s).ToList<Student>();

      Console.WriteLine("Retrieve all Students from the database:");

      foreach (var stdnt in students) {
         string name = stdnt.FirstMidName + " " + stdnt.LastName;
         Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name);
      }
		
      Console.WriteLine("Press any key to exit...");
      Console.ReadKey();
   }
}

Ketika kode di atas dijalankan, Anda akan menerima output berikut.

Adding new students
Retrieve all Students from the database:
ID: 1, Name: Alain Bomer
ID: 2, Name: Mark Upston
Press any key to exit...

Sekarang pertanyaan yang muncul di benak adalah, di mana data dan database di mana kita telah menambahkan beberapa data dan kemudian mengambilnya dari database. Sesuai kesepakatan, DbContext telah membuat database untuk Anda.

  • Jika contoh SQL Express lokal tersedia maka Kode Pertama telah membuat database pada contoh itu.

  • Jika SQL Express tidak tersedia, maka Code First akan mencoba dan menggunakan LocalDb.

  • Database dinamai sesuai nama yang memenuhi syarat dari konteks turunan.

Dalam kasus kami, contoh SQL Express tersedia, dan nama database adalah EFCodeFirstDemo.MyContext seperti yang ditunjukkan pada gambar berikut.

  • Ini hanyalah konvensi default dan ada berbagai cara untuk mengubah database yang digunakan Code First.

  • Seperti yang Anda lihat pada gambar di atas, itu telah membuat tabel Siswa, Kursus dan Pendaftaran dan setiap tabel berisi kolom dengan tipe data dan panjang yang sesuai.

  • Nama kolom dan tipe data juga cocok dengan properti kelas domain masing-masing.

Inisialisasi Database

Pada contoh di atas, kita telah melihat bahwa Code First membuat database secara otomatis, tetapi jika Anda ingin mengubah nama database dan server, mari kita lihat bagaimana Code First memutuskan nama database dan server saat menginisialisasi database. Perhatikan diagram berikut.

Anda dapat menentukan konstruktor dasar dari kelas konteks dengan cara berikut.

  • Tidak Ada Parameter
  • Nama Database
  • Nama String Koneksi

Tidak Ada Parameter

Jika Anda menentukan konstruktor dasar kelas konteks tanpa parameter apa pun seperti yang ditunjukkan dalam contoh di atas, maka kerangka kerja entitas akan membuat database di server SQLEXPRESS lokal Anda dengan nama {Namespace}. {Nama kelas konteks}.

Pada contoh di atas, database yang dibuat secara otomatis memiliki nama EFCodeFirstDemo.MyContext. Jika Anda melihat namanya, Anda akan menemukan bahwa EFCodeFirstDemo adalah namespace dan MyContext adalah nama kelas konteks seperti yang ditunjukkan pada kode berikut.

public class MyContext : DbContext {
   public MyContext() : base() {}

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

Nama Database

Jika Anda meneruskan nama database sebagai parameter di konstruktor dasar kelas konteks, maka Kode Pertama akan membuat database secara otomatis lagi, tetapi kali ini nama akan menjadi yang diteruskan sebagai parameter di konstruktor dasar di server database SQLEXPRESS lokal .

Dalam kode berikut, MyContextDB ditetapkan sebagai parameter di konstruktor dasar. Jika menjalankan aplikasi Anda, maka database dengan nama MyContextDB akan dibuat di server SQL lokal Anda.

public class MyContext : DbContext {
   public MyContext() : base("MyContextDB") {}
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

Nama String Koneksi

Ini adalah cara mudah untuk memberi tahu DbContext untuk menggunakan server database selain SQL Express atau LocalDb. Anda dapat memilih untuk meletakkan string koneksi di file app.config Anda.

  • Jika nama string koneksi cocok dengan nama konteks Anda (baik dengan atau tanpa kualifikasi namespace), maka itu akan ditemukan oleh DbContext ketika parameter less constructor digunakan.

  • Jika nama string koneksi berbeda dari nama konteks Anda, maka Anda dapat memberi tahu DbContext untuk menggunakan koneksi ini dalam mode Code First dengan meneruskan nama string koneksi ke konstruktor DbContext.

public class MyContext : DbContext {
   public MyContext() : base("name = MyContextDB") {}
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}
  • Dalam kode di atas, potongan string koneksi kelas konteks ditentukan sebagai parameter dalam konstruktor dasar.

  • Nama string koneksi harus dimulai dengan "name =" jika tidak, ini akan menganggapnya sebagai nama database.

  • Formulir ini menjelaskan bahwa Anda mengharapkan string koneksi akan ditemukan di file konfigurasi Anda. Pengecualian akan diberikan jika string koneksi dengan nama yang diberikan tidak ditemukan.

<connectionStrings>
   <add name = "MyContextDB"
      connectionString = "Data Source =.;Initial Catalog = EFMyContextDB;Integrated Security = true"
      providerName = "System.Data.SqlClient"/>
</connectionStrings>
  • Nama database dalam string koneksi di app.config adalah EFMyContextDB. CodeFirst akan membuat fileEFMyContextDB database atau gunakan yang sudah ada EFMyContextDB database di SQL Server lokal.

Kelas Domain

Sejauh ini kita baru saja membiarkan EF menemukan model menggunakan konvensi defaultnya, tetapi ada kalanya kelas kita tidak mengikuti konvensi dan kita harus dapat melakukan konfigurasi lebih lanjut. Tetapi Anda dapat mengesampingkan konvensi ini dengan mengonfigurasi kelas domain Anda untuk memberikan informasi yang dibutuhkan EF. Ada dua opsi untuk mengonfigurasi kelas domain Anda -

  • Anotasi Data
  • API Lancar

Anotasi Data

DataAnnotations digunakan untuk mengonfigurasi kelas Anda yang akan menyoroti konfigurasi yang paling sering dibutuhkan. DataAnnotations juga dipahami oleh sejumlah aplikasi .NET, seperti ASP.NET MVC yang memungkinkan aplikasi ini memanfaatkan anotasi yang sama untuk validasi sisi klien.

Berikut anotasi data yang digunakan di kelas siswa.

public class Enrollment {

   [Key]
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }

   [ForeignKey("CourseID")]
   public virtual Course Course { get; set; }

   [ForeignKey("ID")]
   public virtual Student Student { get; set; }
}

API Lancar

Sebagian besar konfigurasi model dapat dilakukan menggunakan anotasi data sederhana. Fluent API adalah cara lanjutan untuk menentukan konfigurasi model yang mencakup semua hal yang dapat dilakukan anotasi data, selain beberapa konfigurasi lanjutan yang tidak dapat dilakukan dengan anotasi data. Anotasi data dan fluent API dapat digunakan bersama.

Untuk mengakses fluent API Anda mengganti metode OnModelCreating di DbContext. Sekarang mari kita ganti nama kolom pada tabel siswa dari FirstMidName menjadi FirstName seperti yang ditunjukkan pada kode berikut.

public class MyContext : DbContext {

   protected override void OnModelCreating(DbModelBuilder modelBuilder) {
      modelBuilder.Entity<Student>().Property(s ⇒ s.FirstMidName)
         .HasColumnName("FirstName");
   }

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

DataAnnotations digunakan untuk mengonfigurasi kelas yang akan menyoroti konfigurasi yang paling sering dibutuhkan. DataAnnotations juga dipahami oleh sejumlah aplikasi .NET, seperti ASP.NET MVC yang memungkinkan aplikasi ini memanfaatkan anotasi yang sama untuk validasi sisi klien. Atribut DataAnnotation menggantikan konvensi CodeFirst default.

System.ComponentModel.DataAnnotations termasuk atribut berikut yang mempengaruhi nullability atau ukuran kolom.

  • Key
  • Timestamp
  • ConcurrencyCheck
  • Required
  • MinLength
  • MaxLength
  • StringLength

System.ComponentModel.DataAnnotations.Schema namespace menyertakan atribut berikut yang memengaruhi skema database.

  • Table
  • Column
  • Index
  • ForeignKey
  • NotMapped
  • InverseProperty

Kunci

Kerangka Kerja Entitas bergantung pada setiap entitas yang memiliki nilai kunci yang digunakannya untuk melacak entitas. Salah satu konvensi yang bergantung pada Code First adalah bagaimana ia menyiratkan properti mana yang merupakan kunci di setiap kelas Code First.

  • Konvensi mencari properti bernama "Id" atau salah satu yang menggabungkan nama kelas dan "Id", seperti "StudentId".

  • Properti akan dipetakan ke kolom kunci utama dalam database.

  • Kelas Pelajar, Kursus dan Pendaftaran mengikuti konvensi ini.

Sekarang anggaplah kelas Student menggunakan nama StdntID sebagai ganti ID. Ketika Code First tidak menemukan properti yang cocok dengan konvensi ini, itu akan memunculkan pengecualian karena persyaratan Entity Framework bahwa Anda harus memiliki properti kunci. Anda dapat menggunakan anotasi kunci untuk menentukan properti mana yang akan digunakan sebagai EntityKey.

Mari kita lihat kode kelas Student berikut yang berisi StdntID, tetapi tidak mengikuti konvensi Code First default. Jadi untuk menangani ini, atribut Key ditambahkan yang akan menjadikannya sebagai kunci utama.

public class Student {

   [Key]
   public int StdntID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Saat Anda menjalankan aplikasi dan melihat ke database Anda di SQL Server Explorer, Anda akan melihat bahwa kunci utama sekarang adalah StdntID di tabel Siswa.

Entity Framework juga mendukung kunci komposit. Composite keysjuga merupakan kunci utama yang terdiri dari lebih dari satu properti. Misalnya, Anda memiliki kelas DrivingLicense yang kunci utamanya adalah kombinasi dari LicenseNumber dan IssuingCountry.

public class DrivingLicense {

   [Key, Column(Order = 1)]
   public int LicenseNumber { get; set; }
   [Key, Column(Order = 2)]
   public string IssuingCountry { get; set; }
   public DateTime Issued { get; set; }
   public DateTime Expires { get; set; }
}

Saat Anda memiliki kunci komposit, Entity Framework mengharuskan Anda untuk menentukan urutan properti kunci. Anda dapat melakukan ini menggunakan anotasi Kolom untuk menentukan pesanan.

Stempel waktu

Code First akan memperlakukan properti Timestamp sama seperti properti ConcurrencyCheck, tetapi juga akan memastikan bahwa bidang database yang pertama kali dibuat kode adalah non-nullable.

  • Lebih umum menggunakan kolom rowversion atau timestamp untuk pemeriksaan konkurensi.

  • Daripada menggunakan anotasi ConcurrencyCheck, Anda dapat menggunakan anotasi TimeStamp yang lebih spesifik selama jenis propertinya adalah byte array.

  • Anda hanya dapat memiliki satu properti stempel waktu di kelas tertentu.

Mari kita lihat contoh sederhana dengan menambahkan properti TimeStamp ke kelas Course -

public class Course {

   public int CourseID { get; set; }
   public string Title { get; set; }
   public int Credits { get; set; }
   [Timestamp]
   public byte[] TStamp { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Seperti yang Anda lihat pada contoh di atas, atribut Timestamp diterapkan ke properti Byte [] kelas Kursus. Jadi, Code First akan membuat kolom timestamp TStampdi tabel Kursus.

ConcurrencyCheck

Anotasi ConcurrencyCheck memungkinkan Anda menandai satu atau beberapa properti yang akan digunakan untuk pemeriksaan konkurensi dalam database saat pengguna mengedit atau menghapus entitas. Jika Anda telah bekerja dengan EF Designer, ini sejalan dengan pengaturan ConcurrencyMode properti ke Tetap.

Mari kita lihat contoh sederhana bagaimana ConcurrencyCheck bekerja dengan menambahkannya ke properti Title di kelas Course.

public class Course {

   public int CourseID { get; set; }
   [ConcurrencyCheck]
   public string Title { get; set; }
   public int Credits { get; set; }
   [Timestamp, DataType("timestamp")]
   public byte[] TimeStamp { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Di kelas Kursus di atas, atribut ConcurrencyCheck diterapkan ke properti Judul yang ada. Sekarang, Kode Pertama akan menyertakan kolom Judul dalam perintah pembaruan untuk memeriksa konkurensi optimis seperti yang ditunjukkan pada kode berikut.

exec sp_executesql N'UPDATE [dbo].[Courses]
   SET [Title] = @0
   WHERE (([CourseID] = @1) AND ([Title] = @2))
   ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Maths',@1=1,@2=N'Calculus'
go

Anotasi yang Diperlukan

Anotasi Wajib memberi tahu EF bahwa properti tertentu diperlukan. Mari kita lihat kelas Mahasiswa berikut di mana Id yang diperlukan ditambahkan ke properti FirstMidName. Atribut wajib akan memaksa EF untuk memastikan bahwa properti tersebut memiliki data di dalamnya.

public class Student {

   [Key]
   public int StdntID { get; set; }

   [Required]
   public string LastName { get; set; }

   [Required]
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Seperti yang terlihat pada contoh di atas, atribut Wajib diterapkan ke FirstMidName dan LastName. Jadi, Code First akan membuat kolom NOT NULL FirstMidName dan LastName di tabel Students seperti yang ditunjukkan pada gambar berikut.

Panjang maksimal

Atribut MaxLength memungkinkan Anda untuk menentukan validasi properti tambahan. Ini dapat diterapkan ke properti tipe string atau array dari kelas domain. EF Code First akan mengatur ukuran kolom seperti yang ditentukan dalam atribut MaxLength.

Mari kita lihat kelas Kursus berikut di mana atribut MaxLength (24) diterapkan ke properti Judul.

public class Course {

   public int CourseID { get; set; }
   [ConcurrencyCheck]
   [MaxLength(24)]
   public string Title { get; set; }
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Ketika Anda menjalankan aplikasi di atas, Kode Pertama akan membuat Judul kolom nvarchar (24) di tabel CourseId seperti yang ditunjukkan pada gambar berikut.

Saat pengguna menyetel Judul yang berisi lebih dari 24 karakter, EF akan menampilkan EntityValidationError.

MinLength

Atribut MinLength juga memungkinkan Anda untuk menentukan validasi properti tambahan, seperti yang Anda lakukan dengan MaxLength. Atribut MinLength juga dapat digunakan dengan atribut MaxLength seperti yang ditunjukkan pada kode berikut.

public class Course {

   public int CourseID { get; set; }
   [ConcurrencyCheck]
   [MaxLength(24) , MinLength(5)]
   public string Title { get; set; }
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

EF akan menampilkan EntityValidationError, jika Anda menetapkan nilai properti Judul kurang dari panjang yang ditentukan dalam atribut MinLength atau lebih besar dari panjang yang ditentukan dalam atribut MaxLength.

StringLength

StringLength juga memungkinkan Anda untuk menentukan validasi properti tambahan seperti MaxLength. Satu-satunya perbedaan adalah atribut StringLength hanya dapat diterapkan ke properti tipe string kelas Domain.

public class Course {

   public int CourseID { get; set; }
   [StringLength (24)]
   public string Title { get; set; }
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Entity Framework juga memvalidasi nilai properti untuk atribut StringLength. Jika pengguna menyetel Judul yang berisi lebih dari 24 karakter, EF akan menampilkan EntityValidationError.

Meja

Kode Default Konvensi pertama membuat nama tabel yang mirip dengan nama kelas. Jika Anda mengizinkan Code First membuat database, dan juga ingin mengubah nama tabel yang dibuatnya. Lalu -

  • Anda dapat menggunakan Code First dengan database yang sudah ada. Tetapi tidak selalu terjadi bahwa nama kelas cocok dengan nama tabel di database Anda.

  • Atribut tabel menggantikan konvensi default ini.

  • EF Code First akan membuat tabel dengan nama yang ditentukan dalam atribut Tabel untuk kelas domain tertentu.

Mari kita lihat contoh berikut di mana kelas bernama Student dan menurut konvensi, Code First menganggap ini akan dipetakan ke tabel bernama Students. Jika bukan itu masalahnya, Anda dapat menentukan nama tabel dengan atribut Tabel seperti yang ditunjukkan pada kode berikut.

[Table("StudentsInfo")]
public class Student {

   [Key]
   public int StdntID { get; set; }
   [Required]
   public string LastName { get; set; }
   [Required]
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Sekarang Anda dapat melihat bahwa atribut Table menetapkan tabel sebagai StudentsInfo. Ketika tabel dibuat, Anda akan melihat nama tabel StudentsInfo seperti yang ditunjukkan pada gambar berikut.

Anda tidak hanya dapat menentukan nama tabel tetapi Anda juga dapat menentukan skema untuk tabel menggunakan atribut Tabel seperti yang ditunjukkan pada kode berikut.

[Table("StudentsInfo", Schema = "Admin")] 
public class Student {

   [Key]
   public int StdntID { get; set; }
   [Required]
   public string LastName { get; set; }
   [Required]
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Anda dapat melihat pada contoh di atas, tabel ditentukan dengan skema admin. Sekarang Code First akan membuat tabel StudentsInfo di skema Admin seperti yang ditunjukkan pada gambar berikut.

Kolom

Ini juga sama dengan atribut Tabel, tetapi atribut Tabel menggantikan perilaku tabel sementara atribut Kolom menggantikan perilaku kolom. Kode Default Pertama, konvensi membuat nama kolom yang mirip dengan nama properti. Jika Anda mengizinkan Code First membuat database, dan juga ingin mengubah nama kolom di tabel Anda. Lalu -

  • Atribut kolom menggantikan konvensi default.

  • EF Code First akan membuat kolom dengan nama yang ditentukan di atribut Kolom untuk properti tertentu.

Mari kita lihat contoh berikut di mana properti bernama FirstMidName dan menurut konvensi, Code First menganggap ini akan dipetakan ke kolom bernama FirstMidName.

Jika tidak demikian, Anda dapat menentukan nama kolom dengan atribut Kolom seperti yang ditunjukkan pada kode berikut.

public class Student {

   public int ID { get; set; }
   public string LastName { get; set; }
   [Column("FirstName")]
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Anda dapat melihat bahwa atribut Column menentukan kolom sebagai FirstName. Ketika tabel dibuat, Anda akan melihat nama kolom FirstName seperti yang ditunjukkan pada gambar berikut.

Indeks

Atribut Indeks diperkenalkan di Entity Framework 6.1. Jika Anda menggunakan versi sebelumnya, informasi di bagian ini tidak berlaku.

  • Anda dapat membuat indeks pada satu atau lebih kolom menggunakan IndexAttribute.

  • Menambahkan atribut ke satu atau lebih properti akan menyebabkan EF membuat indeks yang sesuai dalam database saat membuat database.

  • Indeks membuat pengambilan data lebih cepat dan efisien, dalam banyak kasus. Namun, membebani tabel atau tampilan dengan indeks secara tidak menyenangkan dapat memengaruhi kinerja operasi lain seperti penyisipan atau pembaruan.

  • Pengindeksan adalah fitur baru dalam Entity Framework di mana Anda dapat meningkatkan kinerja aplikasi Code First Anda dengan mengurangi waktu yang diperlukan untuk membuat kueri data dari database.

  • Anda dapat menambahkan indeks ke database Anda menggunakan atribut Indeks, dan mengganti pengaturan Unik dan Berkelompok default untuk mendapatkan indeks yang paling sesuai dengan skenario Anda.

  • Secara default, indeks akan diberi nama IX_ <nama properti>

Mari kita lihat kode berikut di mana atribut Indeks ditambahkan di kelas Kursus untuk Kredit.

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Anda dapat melihat bahwa atribut Index diterapkan ke properti Credits. Saat tabel dibuat, Anda akan melihat IX_Credits di Indeks.

Secara default, indeks tidak unik, tetapi Anda dapat menggunakan IsUniqueparameter bernama untuk menentukan bahwa indeks harus unik. Contoh berikut memperkenalkan indeks unik seperti yang ditunjukkan pada kode berikut.

public class Course {
   public int CourseID { get; set; }
   [Index(IsUnique = true)]
	
   public string Title { get; set; }
   [Index]
	
   public int Credits { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Kunci asing

Konvensi Code First akan menangani hubungan paling umum dalam model Anda, tetapi ada beberapa kasus yang memerlukan bantuan. Misalnya, dengan mengubah nama properti kunci di kelas Siswa membuat masalah dengan hubungannya dengan kelas Pendaftaran.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }
}

public class Student {
   [Key]
   public int StdntID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Saat membuat database, Code First melihat properti StudentID di kelas Enrollment dan mengenalinya, dengan konvensi yang cocok dengan nama kelas ditambah "ID", sebagai kunci asing untuk kelas Student. Namun, tidak ada properti StudentID di kelas Student, tetapi properti StdntID adalah kelas Student.

Solusi untuk ini adalah dengan membuat properti navigasi di Pendaftaran dan menggunakan ForeignKey DataAnnotation untuk membantu Code First memahami cara membangun hubungan antara dua kelas seperti yang ditunjukkan pada kode berikut.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
	
   public Grade? Grade { get; set; }
   public virtual Course Course { get; set; }
   [ForeignKey("StudentID")]
	
   public virtual Student Student { get; set; }
}

Anda sekarang dapat melihat bahwa atribut ForeignKey diterapkan ke properti navigasi.

NotMapped

Secara default, konvensi Code First, setiap properti yang memiliki tipe data yang didukung dan yang menyertakan getter dan setter direpresentasikan dalam database. Tetapi ini tidak selalu terjadi dalam aplikasi Anda. Atribut NotMapped menggantikan konvensi default ini. Misalnya, Anda mungkin memiliki properti di kelas Mahasiswa seperti NamaBapak, tetapi properti itu tidak perlu disimpan. Anda dapat menerapkan atribut NotMapped ke properti FatherName yang tidak ingin Anda buat kolomnya di database seperti yang ditunjukkan pada kode berikut.

public class Student {
   [Key]
   public int StdntID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
	
   public DateTime EnrollmentDate { get; set; }
   [NotMapped]

   public int FatherName { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Anda dapat melihat bahwa atribut NotMapped diterapkan ke properti FatherName. Ketika tabel dibuat, Anda akan melihat bahwa kolom NamaBapak tidak akan dibuat dalam database, tetapi ada di kelas Siswa.

Kode Pertama tidak akan membuat kolom untuk properti, yang tidak memiliki pengambil atau penyetel seperti yang diperlihatkan dalam contoh properti Alamat dan Usia kelas Siswa berikut.

InverseProperty

InverseProperty digunakan ketika Anda memiliki beberapa hubungan antar kelas. Di kelas Pendaftaran, Anda mungkin ingin melacak siapa yang mendaftar Kursus Saat Ini dan Kursus Sebelumnya. Mari tambahkan dua properti navigasi untuk kelas Pendaftaran.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course CurrCourse { get; set; }
   public virtual Course PrevCourse { get; set; }
   public virtual Student Student { get; set; }
}

Demikian pula, Anda juga perlu menambahkan kelas Kursus yang dirujuk oleh properti ini. Kelas Kursus memiliki properti navigasi kembali ke kelas Pendaftaran, yang berisi semua pendaftaran saat ini dan sebelumnya.

public class Course {

   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]

   public int Credits { get; set; }
   public virtual ICollection<Enrollment> CurrEnrollments { get; set; }
   public virtual ICollection<Enrollment> PrevEnrollments { get; set; }
}

Code First membuat kolom foreign key {Class Name} _ {Primary Key}, jika properti foreign key tidak termasuk dalam kelas tertentu seperti yang ditunjukkan pada kelas di atas. Saat database dibuat, Anda akan melihat kunci asing berikut.

Seperti yang Anda lihat, Kode pertama tidak dapat mencocokkan properti di dua kelas itu sendiri. Tabel database untuk Pendaftaran harus memiliki satu kunci asing untuk CurrCourse dan satu untuk PrevCourse, tetapi Kode Pertama akan membuat empat properti kunci asing, yaitu

  • CurrCourse _CourseID
  • PrevCourse _CourseID
  • Course_CourseID, dan
  • Course_CourseID1

Untuk memperbaiki masalah ini, Anda dapat menggunakan anotasi InverseProperty untuk menentukan penyelarasan properti.

public class Course {

   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]

   public int Credits { get; set; }
   [InverseProperty("CurrCourse")]

   public virtual ICollection<Enrollment> CurrEnrollments { get; set; }
   [InverseProperty("PrevCourse")]

   public virtual ICollection<Enrollment> PrevEnrollments { get; set; }
}

Seperti yang Anda lihat, atribut InverseProperty diterapkan di kelas Kursus di atas dengan menentukan properti referensi kelas Pendaftaran yang mana. Sekarang, Code First akan menghasilkan database dan hanya membuat dua kolom kunci asing di tabel Pendaftaran seperti yang ditunjukkan pada gambar berikut.

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Fluent API adalah cara lanjutan untuk menentukan konfigurasi model yang mencakup semua hal yang dapat dilakukan anotasi data selain beberapa konfigurasi lanjutan yang tidak dapat dilakukan dengan anotasi data. Anotasi data dan fluent API dapat digunakan bersama, tetapi Code First mendahulukan Fluent API> anotasi data> konvensi default.

  • Fluent API adalah cara lain untuk mengonfigurasi kelas domain Anda.

  • Code First Fluent API paling sering diakses dengan menimpa metode OnModelCreating pada DbContext turunan Anda.

  • Fluent API menyediakan lebih banyak fungsionalitas untuk konfigurasi daripada DataAnnotations. Fluent API mendukung jenis pemetaan berikut.

Pada bab ini, kita akan melanjutkan dengan contoh sederhana yang berisi kelas Mahasiswa, Kursus dan Pendaftaran dan satu kelas konteks dengan nama MyContext seperti yang ditunjukkan pada kode berikut.

using System.Data.Entity; 
using System.Linq; 
using System.Text;
using System.Threading.Tasks;  

namespace EFCodeFirstDemo {

   class Program {
      static void Main(string[] args) {}
   }
   
   public enum Grade {
      A, B, C, D, F
   }

   public class Enrollment {
      public int EnrollmentID { get; set; }
      public int CourseID { get; set; }
      public int StudentID { get; set; }
      public Grade? Grade { get; set; }
		
      public virtual Course Course { get; set; }
      public virtual Student Student { get; set; }
   }

   public class Student {
      public int ID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
		
      public DateTime EnrollmentDate { get; set; }
		
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }

   public class Course {
      public int CourseID { get; set; }
      public string Title { get; set; }
      public int Credits { get; set; }
		
      public virtual ICollection<Enrollment> Enrollments { get; set; }
   }

   public class MyContext : DbContext {
      public virtual DbSet<Course> Courses { get; set; }
      public virtual DbSet<Enrollment> Enrollments { get; set; }
      public virtual DbSet<Student> Students { get; set; }
   }

}

Untuk mengakses Fluent API, Anda perlu mengganti metode OnModelCreating di DbContext. Mari kita lihat contoh sederhana di mana kita akan mengganti nama kolom pada tabel siswa dari FirstMidName menjadi FirstName seperti yang ditunjukkan pada kode berikut.

public class MyContext : DbContext {

   protected override void OnModelCreating(DbModelBuilder modelBuilder) {
      modelBuilder.Entity<Student>().Property(s ⇒ s.FirstMidName)
      .HasColumnName("FirstName");}

      public virtual DbSet<Course> Courses { get; set; }
      public virtual DbSet<Enrollment> Enrollments { get; set; }
      public virtual DbSet<Student> Students { get; set; }
}

DbModelBuilder digunakan untuk memetakan kelas CLR ke skema database. Ini adalah kelas utama dan di mana Anda dapat mengkonfigurasi semua kelas domain Anda. Pendekatan yang berpusat pada kode untuk membangun Model Data Entitas (EDM) ini dikenal sebagai Kode Pertama.

Fluent API menyediakan sejumlah metode penting untuk mengonfigurasi entitas dan propertinya untuk menimpa berbagai konvensi Code First. Berikut ini beberapa di antaranya.

No Sr Nama Metode & Deskripsi
1

ComplexType<TComplexType>

Mendaftarkan tipe sebagai tipe kompleks dalam model dan mengembalikan objek yang dapat digunakan untuk mengonfigurasi tipe kompleks. Metode ini dapat dipanggil beberapa kali untuk tipe yang sama untuk melakukan beberapa baris konfigurasi.

2

Entity<TEntityType>

Mendaftarkan tipe entitas sebagai bagian dari model dan mengembalikan objek yang dapat digunakan untuk mengkonfigurasi entitas. Metode ini dapat dipanggil berkali-kali untuk entitas yang sama untuk melakukan beberapa baris konfigurasi.

3

HasKey<TKey>

Mengonfigurasi properti kunci utama untuk jenis entitas ini.

4

HasMany<TTargetEntity>

Mengonfigurasi banyak hubungan dari jenis entitas ini.

5

HasOptional<TTargetEntity>

Mengonfigurasi hubungan opsional dari jenis entitas ini. Contoh dari tipe entitas akan dapat disimpan ke database tanpa hubungan ini ditentukan. Kunci asing dalam database akan menjadi nullable.

6

HasRequired<TTargetEntity>

Mengonfigurasi hubungan yang diperlukan dari jenis entitas ini. Contoh dari tipe entitas tidak akan dapat disimpan ke database kecuali hubungan ini ditentukan. Kunci asing dalam database akan menjadi non-nullable.

7

Ignore<TProperty>

Mengecualikan properti dari model sehingga tidak akan dipetakan ke database. (Diwariskan dari StructuralTypeConfiguration <TStructuralType>)

8

Property<T>

Mengonfigurasi properti struct yang ditentukan pada jenis ini. (Diwariskan dari StructuralTypeConfiguration <TStructuralType>)

9

ToTable(String)

Mengonfigurasi nama tabel tempat jenis entitas ini dipetakan.

Fluent API memungkinkan Anda mengonfigurasi entitas atau propertinya, apakah Anda ingin mengubah sesuatu tentang bagaimana mereka memetakan ke database atau bagaimana mereka berhubungan satu sama lain. Ada banyak variasi pemetaan dan pemodelan yang dapat Anda pengaruhi menggunakan konfigurasi. Berikut adalah jenis pemetaan utama yang didukung oleh Fluent API -

  • Pemetaan Entitas
  • Pemetaan Properti

Pemetaan Entitas

Pemetaan entitas hanyalah beberapa pemetaan sederhana yang akan memengaruhi pemahaman Entity Framework tentang bagaimana kelas dipetakan ke database. Semua ini kita diskusikan dalam anotasi data dan di sini kita akan melihat bagaimana mencapai hal yang sama menggunakan Fluent API.

  • Jadi daripada masuk ke kelas domain untuk menambahkan konfigurasi ini, kita bisa melakukan ini di dalam konteks.

  • Hal pertama adalah mengganti metode OnModelCreating, yang memberikan modelBuilder untuk digunakan.

Skema Default

Skema default adalah dbo saat database dibuat. Anda dapat menggunakan metode HasDefaultSchema di DbModelBuilder untuk menentukan skema database yang akan digunakan untuk semua tabel, prosedur tersimpan, dll.

Mari kita lihat contoh berikut di mana skema admin diterapkan.

public class MyContext : DbContext {
   public MyContext() : base("name = MyContextDB") {}

   protected override void OnModelCreating(DbModelBuilder modelBuilder) {
      //Configure default schema
      modelBuilder.HasDefaultSchema("Admin");
   }
	
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

Memetakan Entitas ke Tabel

Dengan konvensi default, Code First akan membuat tabel database dengan nama properti DbSet di kelas konteks seperti Kursus, Pendaftaran, dan Siswa. Tetapi jika Anda menginginkan nama tabel yang berbeda maka Anda dapat mengganti konvensi ini dan dapat memberikan nama tabel yang berbeda dari properti DbSet, seperti yang ditunjukkan pada kode berikut.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   //Map entity to table
   modelBuilder.Entity<Student>().ToTable("StudentData");
   modelBuilder.Entity<Course>().ToTable("CourseDetail");
   modelBuilder.Entity<Enrollment>().ToTable("EnrollmentInfo");
}

Ketika database dibuat, Anda akan melihat nama tabel seperti yang ditentukan dalam metode OnModelCreating.

Pemisahan Entitas (Memetakan Entitas ke Beberapa Tabel)

Pemisahan Entitas memungkinkan Anda menggabungkan data yang berasal dari beberapa tabel ke dalam satu kelas dan hanya dapat digunakan dengan tabel yang memiliki hubungan satu-ke-satu di antara mereka. Mari kita lihat contoh berikut di mana informasi siswa dipetakan menjadi dua tabel.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   //Map entity to table
   modelBuilder.Entity<Student>().Map(sd ⇒ {
      sd.Properties(p ⇒ new { p.ID, p.FirstMidName, p.LastName });
      sd.ToTable("StudentData");
   })

   .Map(si ⇒ {
      si.Properties(p ⇒ new { p.ID, p.EnrollmentDate });
      si.ToTable("StudentEnrollmentInfo");
   });

   modelBuilder.Entity<Course>().ToTable("CourseDetail");
   modelBuilder.Entity<Enrollment>().ToTable("EnrollmentInfo");
}

Pada kode di atas, Anda dapat melihat bahwa entitas Mahasiswa dibagi menjadi dua tabel berikut dengan memetakan beberapa properti ke tabel StudentData dan beberapa properti ke tabel StudentEnrollmentInfo menggunakan metode Peta.

  • StudentData - Berisi Nama Depan dan Nama Belakang Siswa.

  • StudentEnrollmentInfo - Berisi EnrollmentDate.

Saat database dibuat, Anda melihat tabel berikut di database Anda seperti yang diperlihatkan dalam gambar berikut.

Pemetaan Properti

Metode Properti digunakan untuk mengonfigurasi atribut untuk setiap properti milik entitas atau tipe kompleks. Metode Properti digunakan untuk mendapatkan objek konfigurasi untuk properti tertentu. Anda juga dapat memetakan dan mengonfigurasi properti kelas domain Anda menggunakan Fluent API.

Mengonfigurasi Kunci Utama

Konvensi default untuk kunci utama adalah -

  • Kelas mendefinisikan properti yang namanya "ID" atau "Id"
  • Nama kelas diikuti dengan "ID" atau "Id"

Jika kelas Anda tidak mengikuti konvensi default untuk kunci utama seperti yang diperlihatkan dalam kode kelas siswa berikut -

public class Student {
   public int StdntID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Kemudian untuk secara eksplisit mengatur properti menjadi kunci utama, Anda dapat menggunakan metode HasKey seperti yang ditunjukkan pada kode berikut -

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");
	
   // Configure Primary Key
   modelBuilder.Entity<Student>().HasKey<int>(s ⇒ s.StdntID); 
}

Konfigurasi Kolom

Dalam Entity Framework, secara default Code First akan membuat kolom untuk properti dengan nama, urutan, dan tipe data yang sama. Tapi Anda juga bisa mengganti konvensi ini, seperti yang ditunjukkan pada kode berikut.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   //Configure EnrollmentDate Column
   modelBuilder.Entity<Student>().Property(p ⇒ p.EnrollmentDate)
	
   .HasColumnName("EnDate")
   .HasColumnType("DateTime")
   .HasColumnOrder(2);
}

Konfigurasikan Properti MaxLength

Dalam contoh berikut, properti Judul Kursus tidak boleh lebih dari 24 karakter. Ketika pengguna menentukan nilai lebih dari 24 karakter, maka pengguna akan mendapatkan pengecualian DbEntityValidationException.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");
   modelBuilder.Entity<Course>().Property(p ⇒ p.Title).HasMaxLength(24);
}

Konfigurasikan Properti Null atau NotNull

Dalam contoh berikut, properti Judul Kursus diperlukan sehingga metode IsRequired digunakan untuk membuat kolom NotNull. Demikian pula, Student EnrollmentDate bersifat opsional sehingga kami akan menggunakan metode IsOptional untuk mengizinkan nilai null di kolom ini seperti yang ditunjukkan pada kode berikut.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");
   modelBuilder.Entity<Course>().Property(p ⇒ p.Title).IsRequired();
   modelBuilder.Entity<Student>().Property(p ⇒ p.EnrollmentDate).IsOptional();
	
   //modelBuilder.Entity<Student>().Property(s ⇒ s.FirstMidName)
   //.HasColumnName("FirstName"); 
}

Mengonfigurasi Hubungan

Hubungan, dalam konteks database, adalah situasi yang ada antara dua tabel database relasional, ketika satu tabel memiliki kunci asing yang mereferensikan kunci utama dari tabel lainnya. Saat bekerja dengan Code First, Anda menentukan model Anda dengan menentukan kelas CLR domain Anda. Secara default, Entity Framework menggunakan konvensi Code First untuk memetakan kelas Anda ke skema database.

  • Jika Anda menggunakan konvensi penamaan Code First, dalam banyak kasus Anda bisa mengandalkan Code First untuk mengatur hubungan antara tabel Anda berdasarkan foreign key dan properti navigasi.

  • Jika mereka tidak memenuhi konvensi tersebut, ada juga konfigurasi yang dapat Anda gunakan untuk memengaruhi hubungan antar kelas dan bagaimana hubungan tersebut direalisasikan dalam database saat Anda menambahkan konfigurasi di Code First.

  • Beberapa di antaranya tersedia dalam anotasi data dan Anda dapat menerapkan beberapa yang lebih rumit lagi dengan Fluent API.

Konfigurasikan Hubungan Satu-ke-Satu

Saat Anda menentukan hubungan satu-ke-satu dalam model Anda, Anda menggunakan properti navigasi referensi di setiap kelas. Dalam database, kedua tabel hanya dapat memiliki satu rekaman di kedua sisi hubungan. Setiap nilai kunci utama hanya berhubungan dengan satu catatan (atau tidak ada catatan) dalam tabel terkait.

  • Hubungan satu-ke-satu dibuat jika kedua kolom terkait adalah kunci utama atau memiliki batasan unik.

  • Dalam hubungan satu-ke-satu, kunci utama bertindak sebagai kunci asing dan tidak ada kolom kunci asing terpisah untuk tabel mana pun.

  • Jenis hubungan ini tidak umum karena sebagian besar informasi yang terkait dengan cara ini semuanya akan berada dalam satu tabel.

Mari kita lihat contoh berikut di mana kita akan menambahkan kelas lain ke dalam model kita untuk membuat hubungan satu-ke-satu.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual StudentLogIn StudentLogIn { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

public class StudentLogIn {
   [Key, ForeignKey("Student")]
   public int ID { get; set; }
   public string EmailID { get; set; }
   public string Password { get; set; }
	
   public virtual Student Student { get; set; }
}

Seperti yang Anda lihat pada kode di atas bahwa atribut Key dan ForeignKey digunakan untuk properti ID di kelas StudentLogIn, untuk menandainya sebagai Primary Key dan juga Foreign Key.

Untuk mengonfigurasi hubungan satu-ke-nol atau satu antara Student dan StudentLogIn menggunakan Fluent API, Anda perlu mengganti metode OnModelCreating seperti yang ditunjukkan pada kode berikut.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   // Configure ID as PK for StudentLogIn
   modelBuilder.Entity<StudentLogIn>()
   .HasKey(s ⇒ s.ID);

   // Configure ID as FK for StudentLogIn
   modelBuilder.Entity<Student>()
   
   .HasOptional(s ⇒ s.StudentLogIn) //StudentLogIn is optional
   .WithRequired(t ⇒ t.Student); // Create inverse relationship
}

Dalam kebanyakan kasus, Kerangka Entitas dapat menyimpulkan tipe mana yang dependen dan mana yang menjadi prinsipal dalam suatu hubungan. Namun, ketika kedua ujung hubungan diperlukan atau kedua sisi bersifat opsional, Kerangka Kerja Entitas tidak dapat mengidentifikasi dependen dan prinsipal. Saat kedua ujung hubungan diperlukan, Anda dapat menggunakan HasRequired seperti yang ditunjukkan pada kode berikut.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   // Configure ID as PK for StudentLogIn
   modelBuilder.Entity<StudentLogIn>()
   .HasKey(s ⇒ s.ID);

   // Configure ID as FK for StudentLogIn
   modelBuilder.Entity<Student>()
   .HasRequired(r ⇒ r.Student)
   .WithOptional(s ⇒ s.StudentLogIn);  
}

Ketika database dibuat, Anda akan melihat bahwa hubungan dibuat seperti yang ditunjukkan pada gambar berikut.

Konfigurasikan Hubungan Satu-ke-Banyak

Tabel kunci utama berisi hanya satu rekaman yang terkait dengan tidak ada, satu, atau banyak rekaman dalam tabel terkait. Ini adalah jenis hubungan yang paling umum digunakan.

  • Dalam jenis hubungan ini, baris dalam tabel A dapat memiliki banyak baris yang cocok dalam tabel B, tetapi baris dalam tabel B hanya dapat memiliki satu baris yang cocok dalam tabel A.

  • Kunci asing ditentukan pada tabel yang mewakili banyak ujung hubungan.

  • Misalnya, dalam diagram di atas tabel Siswa dan Pendaftaran memiliki hubungan satu-tomany, setiap siswa mungkin memiliki banyak pendaftaran, tetapi setiap pendaftaran hanya dimiliki oleh satu siswa.

Di bawah ini adalah Pelajar dan Pendaftaran yang memiliki hubungan satu ke banyak, tetapi kunci asing dalam tabel Pendaftaran tidak mengikuti konvensi Kode Pertama default.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
	
   //StdntID is not following code first conventions name
   public int StdntID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }
}

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual StudentLogIn StudentLogIn { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Dalam kasus ini, untuk mengonfigurasi hubungan satu-ke-banyak menggunakan Fluent API, Anda perlu menggunakan metode HasForeignKey seperti yang ditunjukkan pada kode berikut.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   //Configure FK for one-to-many relationship
   modelBuilder.Entity<Enrollment>()

   .HasRequired<Student>(s ⇒ s.Student)
   .WithMany(t ⇒ t.Enrollments)
   .HasForeignKey(u ⇒ u.StdntID);  
}

Ketika database dibuat, Anda akan melihat bahwa hubungan dibuat seperti yang ditunjukkan pada gambar berikut.

Dalam contoh di atas, metode HasRequired menetapkan bahwa properti navigasi Student harus Null. Jadi, Anda harus menetapkan Siswa dengan entitas Pendaftaran setiap kali Anda menambah atau memperbarui Pendaftaran. Untuk menangani ini kita perlu menggunakan metode HasOptional daripada metode HasRequired.

Konfigurasikan Hubungan Banyak-ke-Banyak

Setiap rekaman di kedua tabel bisa terkait dengan sejumlah rekaman (atau tanpa rekaman) di tabel lain.

  • Anda dapat membuat hubungan seperti itu dengan menentukan tabel ketiga, yang disebut tabel persimpangan, yang kunci utamanya terdiri dari kunci asing dari tabel A dan tabel B.

  • Misalnya, tabel siswa dan tabel kursus memiliki hubungan banyak ke banyak.

Berikut ini adalah kelas Student dan Course dimana Student dan Course memiliki banyak hubungan, karena kedua kelas tersebut memiliki properti navigasi Students dan Course yang merupakan kumpulan. Dengan kata lain, satu entitas memiliki kumpulan entitas lain.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Course> Courses { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   public int Credits { get; set; }
	
   public virtual ICollection<Student> Students { get; set; }
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Untuk mengonfigurasi hubungan banyak-ke-banyak antara Siswa dan Kursus, Anda dapat menggunakan Fluent API seperti yang diperlihatkan dalam kode berikut.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   // Configure many-to-many relationship
   modelBuilder.Entity<Student>()
   .HasMany(s ⇒ s.Courses) 
   .WithMany(s ⇒ s.Students);
}

Konvensi Kode Pertama default digunakan untuk membuat tabel gabungan saat database dibuat. Hasilnya, tabel StudentCourses dibuat dengan kolom Course_CourseID dan Student_ID seperti yang ditunjukkan pada gambar berikut.

Jika Anda ingin menentukan nama tabel gabungan dan nama kolom dalam tabel, Anda perlu melakukan konfigurasi tambahan dengan menggunakan metode Peta.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {

   //Configure default schema
   modelBuilder.HasDefaultSchema("Admin");

   // Configure many-to-many relationship 
   modelBuilder.Entity<Student>()

   .HasMany(s ⇒ s.Courses)
   .WithMany(s ⇒ s.Students)
   
   .Map(m ⇒ {
      m.ToTable("StudentCoursesTable");
      m.MapLeftKey("StudentID");
      m.MapRightKey("CourseID");
   }); 
}

Anda dapat melihat ketika database dibuat, nama tabel dan kolom dibuat seperti yang ditentukan pada kode di atas.

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Dalam Entity Framework, Seed diperkenalkan di EF 4.1 dan bekerja dengan penginisialisasi database. Ide umum dari aSeed Methodadalah menginisialisasi data ke dalam database yang dibuat oleh Code First atau dikembangkan oleh Migrasi. Data ini sering kali merupakan data pengujian, tetapi juga dapat menjadi data referensi seperti daftar Siswa yang diketahui, Kursus, dll. Ketika data diinisialisasi, lakukan hal berikut -

  • Memeriksa apakah database target sudah ada atau belum.
  • Jika ya, maka model Code First saat ini dibandingkan dengan model yang disimpan dalam metadata di database.
  • Database akan dihapus jika model saat ini tidak cocok dengan model dalam database.
  • Basis data dibuat jika dihapus atau tidak ada sejak awal.
  • Jika database telah dibuat, maka metode Seed penginisialisasi dipanggil.

Metode Seed mengambil objek konteks database sebagai parameter input, dan kode dalam metode tersebut menggunakan objek tersebut untuk menambahkan entitas baru ke database. Untuk memasukkan data ke dalam database Anda, Anda perlu mengganti metode Seed. Mari kita lihat contoh berikut di mana beberapa data default dimulai ke database di kelas internal.

private class UniDBInitializer<T> : DropCreateDatabaseAlways<MyContext> {

   protected override void Seed(MyContext context) {

      IList<Student> students = new List<Student>();

      students.Add(new Student() {
         FirstMidName = "Andrew", 
         LastName = "Peters", 
         EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
      });

      students.Add(new Student() {
         FirstMidName = "Brice", 
         LastName = "Lambson", 
         EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
      });

      students.Add(new Student() {
         FirstMidName = "Rowan", 
         LastName = "Miller", 
         EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
      });

      foreach (Student student in students)
      context.Students.Add(student);
      base.Seed(context);
   }
}

Pada kode di atas, tabel siswa diinisialisasi. Anda perlu mengatur kelas penginisialisasi DB ini dalam kelas konteks seperti yang ditunjukkan pada kode berikut.

public MyContext() : base("name=MyContextDB") {
   Database.SetInitializer<MyContext>(new UniDBInitializer<MyContext>());
}

Berikut ini adalah implementasi kelas lengkap dari kelas MyContext, yang juga berisi kelas penginisialisasi DB.

public class MyContext : DbContext {

   public MyContext() : base("name=MyContextDB") {
      Database.SetInitializer<MyContext>(new UniDBInitializer<MyContext>());
   }

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
	
   private class UniDBInitializer<T> : DropCreateDatabaseAlways<MyContext> {

      protected override void Seed(MyContext context) {

         IList<Student> students = new List<Student>();
			
         students.Add(new Student() {
            FirstMidName = "Andrew", 
            LastName = "Peters", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString()) 
         });

         students.Add(new Student() {
            FirstMidName = "Brice", 
            LastName = "Lambson", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         });

         students.Add(new Student() {
            FirstMidName = "Rowan", 
            LastName = "Miller", 
            EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         });

         foreach (Student student in students)
         context.Students.Add(student);
         base.Seed(context);
      }
   } 
}

Ketika contoh di atas dikompilasi dan dijalankan, Anda dapat melihat datanya dalam database seperti yang ditunjukkan pada gambar berikut.

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Entity Framework 4.3 menyertakan fitur Migrasi Pertama Kode baru yang memungkinkan Anda mengembangkan skema database secara bertahap saat model Anda berubah seiring waktu. Untuk sebagian besar pengembang, ini adalah peningkatan besar atas opsi penginisialisasi database dari rilis 4.1 dan 4.2 yang mengharuskan Anda memperbarui database secara manual atau melepaskan dan membuatnya kembali saat model Anda berubah.

  • Sebelum Entity Framework 4.3, jika Anda sudah memiliki data (selain data seed) atau Stored Procedures, trigger, dll. Di database Anda, strategi ini digunakan untuk membuang seluruh database dan membuatnya kembali, sehingga Anda akan kehilangan data dan DB lainnya. benda.

  • Dengan migrasi, itu akan secara otomatis memperbarui skema database, ketika model Anda berubah tanpa kehilangan data yang ada atau objek database lainnya.

  • Ini menggunakan penginisialisasi database baru yang disebut MigrateDatabaseToLatestVersion.

Ada dua jenis Migrasi -

  • Migrasi Otomatis
  • Migrasi berbasis kode

Migrasi Otomatis

Migrasi Otomatis pertama kali diperkenalkan dalam kerangka Entitas 4.3. Dalam migrasi otomatis, Anda tidak perlu memproses migrasi database secara manual di file kode. Misalnya, untuk setiap perubahan, Anda juga perlu mengubah kelas domain Anda. Tetapi dengan migrasi otomatis Anda hanya perlu menjalankan perintah di Package Manager Console untuk menyelesaikannya.

Mari kita lihat proses langkah demi langkah migrasi otomatis berikut.

Saat Anda menggunakan pendekatan Code First, Anda tidak memiliki database untuk aplikasi Anda.

Dalam contoh ini kita akan memulai dengan 3 kelas dasar kita seperti Mahasiswa, Kursus dan Pendaftaran seperti yang ditunjukkan pada kode berikut.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }

}

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

Berikut adalah kelas konteksnya.

public class MyContext : DbContext {
   public MyContext() : base("MyContextDB") {}
   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }
}

Sebelum menjalankan aplikasi, Anda perlu mengaktifkan migrasi otomatis.

Step 1 - Buka Package Manger Console dari Tools → NuGet Package Manger → Package Manger Console.

Step 2 - Untuk mengaktifkan migrasi otomatis, jalankan perintah berikut di Package Manager Console.

PM> enable-migrations -EnableAutomaticMigrations:$true

Step 3 - Setelah perintah berhasil dijalankan, itu membuat kelas Konfigurasi tertutup internal di folder Migrasi proyek Anda seperti yang ditunjukkan pada kode berikut.

namespace EFCodeFirstDemo.Migrations {

   using System;
   using System.Data.Entity;
   using System.Data.Entity.Migrations;
   using System.Linq;
	
   internal sealed class Configuration : DbMigrationsConfiguration<EFCodeFirstDemo.MyContext> {

      public Configuration() {
         AutomaticMigrationsEnabled = true;
         ContextKey = "EFCodeFirstDemo.MyContext";
      }

      protected override void Seed(EFCodeFirstDemo.MyContext context) {

         //  This method will be called after migrating to the latest version.
         //  You can use the DbSet<T>.AddOrUpdate() helper extension method
         //  to avoid creating duplicate seed data. E.g.

         //  context.People.AddOrUpdate(
            //  p ⇒ p.FullName, 
            //  new Person { FullName = "Andrew Peters" }, 
            //  new Person { FullName = "Brice Lambson" }, 
            //  new Person { FullName = "Rowan Miller" }
         //  );
      }
   }
}

Step 4 - Tetapkan penginisialisasi database di kelas konteks dengan strategi inisialisasi DB baru MigrateDatabaseToLatestVersion.

public class MyContext : DbContext {

   public MyContext() : base("MyContextDB") {
      Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, 
         EFCodeFirstDemo.Migrations.Configuration>("MyContextDB"));
   }

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }

}

Step 5- Anda telah menyiapkan migrasi otomatis. Saat Anda menjalankan aplikasi Anda, maka secara otomatis akan menangani migrasi, saat Anda mengubah model.

Step 6- Seperti yang Anda lihat, satu tabel sistem __MigrationHistory juga dibuat di database Anda dengan tabel lain. Di __MigrationHistory, migrasi otomatis menyimpan riwayat perubahan basis data.

Step 7- Ketika Anda menambahkan kelas entitas lain sebagai kelas domain Anda dan menjalankan aplikasi Anda, maka itu akan membuat tabel di database Anda. Mari tambahkan kelas StudentLogIn berikut.

public class StudentLogIn {
   [Key, ForeignKey("Student")]
   public int ID { get; set; }
   public string EmailID { get; set; }
   public string Password { get; set; }
	
   public virtual Student Student { get; set; }
}

Step 8 - Jangan lupa menambahkan DBSet untuk kelas yang disebutkan di atas dalam kelas konteks Anda seperti yang ditunjukkan pada kode berikut.

public virtual DbSet<StudentLogIn> StudentsLogIn { get; set; }

Step 9 - Jalankan aplikasi Anda lagi dan Anda akan melihat bahwa tabel StudentsLogIn telah ditambahkan ke database Anda.

Langkah-langkah yang disebutkan di atas untuk migrasi otomatis hanya akan berfungsi untuk entitas Anda. Misalnya, untuk menambahkan kelas entitas lain atau menghapus kelas entitas yang ada itu akan berhasil dimigrasi. Tetapi jika Anda menambahkan atau menghapus properti apa pun ke kelas entitas Anda, maka itu akan memunculkan pengecualian.

Step 10 - Untuk menangani migrasi properti Anda perlu menyetel AutomaticMigrationDataLossAllowed = true dalam konstruktor kelas konfigurasi.

public Configuration() {
   AutomaticMigrationsEnabled = true;
   AutomaticMigrationDataLossAllowed = true;
   ContextKey = "EFCodeFirstDemo.MyContext";
}

Migrasi Berbasis Kode

Saat Anda mengembangkan aplikasi baru, model data Anda sering berubah, dan setiap kali model berubah, model tersebut tidak sinkron dengan database. Anda telah mengkonfigurasi Entity Framework untuk secara otomatis menjatuhkan dan membuat ulang database setiap kali Anda mengubah model data. Migrasi berbasis kode berguna ketika Anda menginginkan kontrol lebih pada migrasi.

  • Saat Anda menambahkan, menghapus, atau mengubah kelas entitas atau mengubah kelas DbContext Anda, saat berikutnya Anda menjalankan aplikasi, secara otomatis menghapus database yang sudah ada, membuat database baru yang cocok dengan model, dan menyemainya dengan data pengujian.

  • Fitur Migrasi Pertama Kode memecahkan masalah ini dengan mengaktifkan Kode Pertama untuk memperbarui skema basis data alih-alih menghapus dan membuat ulang basis data. Untuk menerapkan aplikasi, Anda harus mengaktifkan Migrasi.

Berikut adalah aturan dasar untuk memigrasi perubahan dalam database -

  • Aktifkan Migrasi
  • Tambahkan Migrasi
  • Perbarui Database

Mari kita lihat proses langkah demi langkah migrasi basis kode berikut.

Saat Anda menggunakan pendekatan pertama kode, Anda tidak memiliki database untuk aplikasi Anda.

Dalam contoh ini kita akan memulai lagi dengan 3 kelas dasar kita seperti Pelajar, Kursus dan Pendaftaran seperti yang ditunjukkan pada kode berikut.

public class Enrollment {
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
	
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }

}

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

public class Course {
   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]
   public int Credits { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

Berikut adalah kelas konteksnya.

public class MyContext : DbContext {

   public MyContext() : base("MyContextDB") {
      Database.SetInitializer(new MigrateDatabaseToLatestVersion<
         MyContext, EFCodeFirstDemo.Migrations.Configuration>("MyContextDB"));
   }

   public virtual DbSet<Course> Courses { get; set; }
   public virtual DbSet<Enrollment> Enrollments { get; set; }
   public virtual DbSet<Student> Students { get; set; }

}

Step 1 - Sebelum menjalankan aplikasi, Anda perlu mengaktifkan migrasi.

Step 2 - Buka Konsol Pengelola Paket dari Tools → NuGet Package Manger → Package Manger Console.

Step 3 - Migrasi sudah diaktifkan, sekarang tambahkan migrasi di aplikasi Anda dengan menjalankan perintah berikut.

PM> add-migration "UniDB Schema"

Step 4 - Ketika perintah berhasil dijalankan maka Anda akan melihat file baru telah dibuat di folder Migrasi dengan nama parameter yang Anda berikan ke perintah dengan awalan stempel waktu seperti yang ditunjukkan pada gambar berikut.

Step 5 - Anda dapat membuat atau memperbarui database menggunakan perintah "update-database".

PM> Update-Database -Verbose

Bendera "-Verbose" menentukan untuk menampilkan Pernyataan SQL yang diterapkan ke database target di konsol.

Step 6 - Mari tambahkan satu properti lagi 'Usia' di kelas siswa lalu jalankan pernyataan pembaruan.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public int Age { get; set; }
   public DateTime EnrollmentDate { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

}

Saat Anda menjalankan PM → Update-Database –Verbose, ketika perintah berhasil dijalankan Anda akan melihat kolom baru Age ditambahkan ke database Anda.

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Dalam bab ini, kita akan mempelajari cara memigrasi perubahan ke dalam database saat ada beberapa kelas DbContext dalam aplikasi.

  • Beberapa DbContext pertama kali diperkenalkan di Entity Framework 6.0.
  • Beberapa kelas konteks mungkin termasuk dalam satu database atau dua database yang berbeda.

Dalam contoh kami, kami akan mendefinisikan dua kelas Konteks untuk database yang sama. Dalam kode berikut, ada dua kelas DbContext untuk Siswa dan Guru.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
}

public class MyStudentContext : DbContext {
   public MyStudentContext() : base("UniContextDB") {}
   public virtual DbSet<Student> Students { get; set; }
}

public class Teacher {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime HireDate { get; set; }
}

public class MyTeacherContext : DbContext {
   public MyTeacherContext() : base("UniContextDB") {}
   public virtual DbSet<Teacher> Teachers { get; set; }
}

Seperti yang Anda lihat pada kode di atas, ada dua model yang disebut "Siswa" dan "Guru". Masing-masing dikaitkan dengan kelas konteks tertentu yang sesuai, yaitu, Siswa dikaitkan dengan MyStudentContext dan Guru dikaitkan dengan MyTeacherContext.

Berikut adalah aturan dasar untuk memigrasi perubahan dalam database, ketika ada beberapa kelas Konteks dalam proyek yang sama.

  • aktifkan-migrasi -ContextTypeName <DbContext-Name-with-Namespaces> MigrationsDirectory: <Migrations-Directory-Name>

  • Add-Migration -configuration <DbContext-Migrations-Configuration-Class-withNamespaces> <Migrations-Name>

  • Perbarui-Database -configuration <DbContext-Migrations-Configuration-Class-withNamespaces> -Verbose

Mari aktifkan migrasi untuk MyStudentContext dengan menjalankan perintah berikut di Package Manager Console.

PM→ enable-migrations -ContextTypeName:EFCodeFirstDemo.MyStudentContext

Setelah dijalankan, kami akan menambahkan model dalam riwayat migrasi dan untuk itu, kami harus mengaktifkan perintah add-migrasi di konsol yang sama.

PM→ add-migration -configuration EFCodeFirstDemo.Migrations.Configuration Initial

Sekarang mari kita tambahkan beberapa data ke dalam tabel Siswa dan Guru di database.

static void Main(string[] args) {

   using (var context = new MyStudentContext()) {
	
      //// Create and save a new Students
      Console.WriteLine("Adding new students");

      var student = new Student {
         FirstMidName = "Alain", 
         LastName = "Bomer", 
         EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         //Age = 24
      };

      context.Students.Add(student);

      var student1 = new Student {
         FirstMidName = "Mark",
         LastName = "Upston", 
         EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
         //Age = 30
      };

      context.Students.Add(student1);
      context.SaveChanges();
      // Display all Students from the database
      var students = (from s in context.Students orderby s.FirstMidName
         select s).ToList<Student>();
		
      Console.WriteLine("Retrieve all Students from the database:");

      foreach (var stdnt in students) {
         string name = stdnt.FirstMidName + " " + stdnt.LastName;
         Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name);
      }

      Console.WriteLine("Press any key to exit...");
      Console.ReadKey();
   }

   using (var context = new MyTeacherContext()) {

      //// Create and save a new Teachers
      Console.WriteLine("Adding new teachers");

      var student = new Teacher {
         FirstMidName = "Alain", 
         LastName = "Bomer", 
         HireDate = DateTime.Parse(DateTime.Today.ToString())
         //Age = 24
      };

      context.Teachers.Add(student);

      var student1 = new Teacher {
         FirstMidName = "Mark", 
         LastName = "Upston", 
         HireDate = DateTime.Parse(DateTime.Today.ToString())
         //Age = 30
      };

      context.Teachers.Add(student1);
      context.SaveChanges();
  
      // Display all Teachers from the database
      var teachers = (from t in context.Teachers orderby t.FirstMidName
         select t).ToList<Teacher>();
		
      Console.WriteLine("Retrieve all teachers from the database:");

      foreach (var teacher in teachers) {
         string name = teacher.FirstMidName + " " + teacher.LastName;
         Console.WriteLine("ID: {0}, Name: {1}", teacher.ID, name);
      }

      Console.WriteLine("Press any key to exit...");
      Console.ReadKey();
   }
}

Ketika kode di atas dijalankan, Anda akan melihat bahwa dua tabel berbeda dibuat untuk dua model berbeda seperti yang ditunjukkan pada gambar berikut.

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.

Sebelum Entity Framework 6, Entity Framework tidak mengenali entitas atau tipe kompleks yang bersarang di dalam entitas atau tipe kompleks lainnya. Saat Entity Framework membuat model, tipe bertingkat menghilang begitu saja.

Mari kita lihat contoh sederhana di mana kami memiliki model dasar kami dengan tiga entitas Siswa, Kursus dan Pendaftaran.

  • Mari tambahkan Identitas properti, yang merupakan tipe Person. Orang adalah entitas lain, berisi properti BirthDate dan FatherName.

  • Dalam istilah Entity Framework, karena tidak memiliki identitas dan merupakan bagian dari entitas, ini adalah tipe kompleks Kerangka Kerja Entitas, dan kami sebenarnya memiliki dukungan untuk tipe kompleks sejak versi pertama Kerangka Entitas.

  • Jenis Orang tidak bersarang seperti yang ditunjukkan pada kode berikut.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
   public Person Identity { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

public class Person {

   public Person(string fatherName, DateTime birthDate) {
      FatherName = fatherName;
      BirthDate = birthDate;
   }
	
   public string FatherName { get; set; }
   public DateTime BirthDate { get; set; }
}

Kerangka Kerja Entitas akan tahu cara mempertahankan tipe Orang saat digunakan di versi sebelumnya juga.

Dengan menggunakan Entity Framework Power Tool kita akan melihat bagaimana Entity Framework menafsirkan model tersebut. Klik kanan pada file Program.cs dan pilih Entity Framework → View Entity Data Model (Read only)

Sekarang Anda akan melihat bahwa properti Identity didefinisikan di kelas Student.

Jika kelas Person ini tidak akan digunakan oleh entitas lain, maka kita dapat menumpuknya di dalam kelas Student, tetapi versi sebelumnya dari Entity Framework tidak mengakui tipe bertingkat.

Di versi yang lebih lama, Anda menghasilkan model lagi, tidak hanya jenisnya tidak dikenali, tetapi karena tidak ada, propertinya juga tidak ada, jadi Entity Framework tidak akan mempertahankan jenis Person sama sekali.

public class Student {
   public int ID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
	
   public DateTime EnrollmentDate { get; set; }
   public Person Identity { get; set; }
	
   public virtual ICollection<Enrollment> Enrollments { get; set; }

   public class Person {

      public Person(string fatherName, DateTime birthDate) {
         FatherName = fatherName;
         BirthDate = birthDate;
      }

      public string FatherName { get; set; }
      public DateTime BirthDate { get; set; }
   }
}

Dengan Entity Framework 6, entitas bertingkat dan tipe kompleks dikenali. Pada kode di atas, Anda dapat melihat bahwa Person ada di dalam kelas Student.

Saat Anda menggunakan Entity Framework Power Tool untuk memperlihatkan bagaimana Entity Framework menginterpretasikan model kali ini, terdapat properti Identity yang sebenarnya, dan tipe kompleks Person. Jadi Entity Framework akan menyimpan data tersebut.

Sekarang Anda dapat melihat bahwa Identity adalah tipe entitas bertingkat, yang tidak didukung sebelum Entity Framework 6.

Kami menyarankan Anda untuk menjalankan contoh di atas dengan cara langkah demi langkah untuk pemahaman yang lebih baik.