Membuat Model Data Kerangka Kerja Entitas untuk Aplikasi MVC ASP.NET (1 dari 10)
oleh Tom Dykstra
Catatan
Versi yang lebih baru dari seri tutorial ini tersedia, untuk Visual Studio 2013, Entity Framework 6, dan MVC 5.
Aplikasi web sampel Contoso University menunjukkan cara membuat aplikasi ASP.NET MVC 4 menggunakan Entity Framework 5 dan Visual Studio 2012. Aplikasi sampel adalah situs web untuk Universitas Contoso fiktif. Ini termasuk fungsionalitas seperti penerimaan siswa, pembuatan kursus, dan tugas instruktur. Seri tutorial ini menjelaskan cara membangun aplikasi sampel Contoso University.
Code First
Ada tiga cara untuk bekerja dengan data dalam Kerangka Kerja Entitas: Database Pertama, Model Pertama, dan Kode Terlebih Dahulu. Tutorial ini untuk Code First. Untuk informasi tentang perbedaan antara alur kerja ini dan panduan tentang cara memilih yang terbaik untuk skenario Anda, lihat Alur Kerja Pengembangan Kerangka Kerja Entitas.
MVC
Aplikasi sampel dibangun di atas ASP.NET MVC. Jika Anda lebih suka bekerja dengan model ASP.NET Web Forms, lihat seri tutorial Pengikatan Model dan Formulir Web dan ASP.NET Peta Konten Akses Data.
Versi perangkat lunak
Ditampilkan dalam tutorial Juga berfungsi dengan Windows 8 Windows 7 Visual Studio 2012 Visual Studio 2012 Express untuk Web. Ini secara otomatis diinstal oleh Windows Azure SDK jika Anda belum memiliki VS 2012 atau VS 2012 Express untuk Web. Visual Studio 2013 harus berfungsi, tetapi tutorial belum diuji dengannya, dan beberapa pilihan menu dan kotak dialog berbeda. Versi VS 2013 dari Windows Azure SDK diperlukan untuk penyebaran Windows Azure. .NET 4.5 Sebagian besar fitur yang ditampilkan akan berfungsi di .NET 4, tetapi beberapa tidak akan. Misalnya, dukungan enum di EF memerlukan .NET 4.5. Kerangka Kerja Entitas 5 Windows Azure SDK 2.1 Jika Anda melewati langkah-langkah penyebaran Windows Azure, Anda tidak memerlukan SDK. Saat versi baru SDK dirilis, tautan akan menginstal versi yang lebih baru. Dalam hal ini, Anda mungkin harus menyesuaikan beberapa instruksi ke UI dan fitur baru. Pertanyaan
Jika Anda memiliki pertanyaan yang tidak terkait langsung dengan tutorial, Anda dapat mempostingnya ke forum Kerangka Kerja Entitas ASP.NET, Kerangka Kerja Entitas dan LINQ ke forum Entitas, atau StackOverflow.com.
Ucapan terima kasih
Lihat tutorial terakhir dalam seri untuk pengakuan dan catatan tentang VB.
Aplikasi Web Contoso University
Aplikasi yang akan Anda bangun dalam tutorial ini adalah situs web universitas sederhana.
Pengguna dapat melihat dan memperbarui informasi siswa, kursus, dan instruktur. Berikut adalah beberapa layar yang akan Anda buat.
Gaya UI situs ini telah disimpan dekat dengan apa yang dihasilkan oleh templat bawaan, sehingga tutorial dapat berfokus terutama pada cara menggunakan Kerangka Kerja Entitas.
Prasyarat
Petunjuk arah dan cuplikan layar dalam tutorial ini mengasumsikan bahwa Anda menggunakan Visual Studio 2012 atau Visual Studio 2012 Express untuk Web, dengan pembaruan terbaru dan Azure SDK untuk .NET yang diinstal per Juli 2013. Anda bisa mendapatkan semua ini dengan tautan berikut:
Azure SDK untuk .NET (Visual Studio 2012)
Jika Anda telah menginstal Visual Studio, tautan di atas akan menginstal komponen yang hilang. Jika Anda tidak memiliki Visual Studio, tautan akan menginstal Visual Studio 2012 Express untuk Web. Anda dapat menggunakan Visual Studio 2013, tetapi beberapa prosedur dan layar yang diperlukan akan berbeda.
Membuat Aplikasi Web MVC
Buka Visual Studio dan buat proyek C# baru bernama "ContosoUniversity" menggunakan templat Aplikasi Web MVC 4 ASP.NET. Pastikan Anda menargetkan .NET Framework 4.5 (Anda akan menggunakan enum
properti, dan yang memerlukan .NET 4.5).
Dalam kotak dialog Proyek MVC 4 ASP.NET baru pilih templat Aplikasi Internet.
Biarkan mesin tampilan Razor dipilih, dan biarkan kotak centang Buat proyek pengujian unit dikosongkan.
Klik OK.
Menyiapkan Gaya Situs
Beberapa perubahan sederhana akan menyiapkan menu situs, tata letak, dan beranda.
Buka Views\Shared\_Layout.cshtml, dan ganti konten file dengan kode berikut. Perubahan disorot.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title - Contoso University</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<header>
<div class="content-wrapper">
<div class="float-left">
<p class="site-title">@Html.ActionLink("Contoso University", "Index", "Home")</p>
</div>
<div class="float-right">
<section id="login">
@Html.Partial("_LoginPartial")
</section>
<nav>
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Students", "Index", "Student")</li>
<li>@Html.ActionLink("Courses", "Index", "Course")</li>
<li>@Html.ActionLink("Instructors", "Index", "Instructor")</li>
<li>@Html.ActionLink("Departments", "Index", "Department")</li>
</ul>
</nav>
</div>
</div>
</header>
<div id="body">
@RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
@RenderBody()
</section>
</div>
<footer>
<div class="content-wrapper">
<div class="float-left">
<p>© @DateTime.Now.Year - Contoso University</p>
</div>
</div>
</footer>
@Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)
</body>
</html>
Pembaruan kode ini membuat perubahan berikut:
- Mengganti contoh templat "Aplikasi MVC ASP.NET Saya" dan "logo Anda di sini" dengan "Universitas Contoso".
- Menambahkan beberapa tautan tindakan yang akan digunakan nanti dalam tutorial.
Di Views\Home\Index.cshtml, ganti konten file dengan kode berikut untuk menghilangkan paragraf templat tentang ASP.NET dan MVC:
@{
ViewBag.Title = "Home Page";
}
@section featured {
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
<h2>@ViewBag.Message</h2>
</hgroup>
</div>
</section>
}
Di Controllers\HomeController.cs, ubah nilai untuk ViewBag.Message
dalam Index
metode Tindakan menjadi "Selamat Datang di Contoso University!", seperti yang ditunjukkan dalam contoh berikut:
public ActionResult Index()
{
ViewBag.Message = "Welcome to Contoso University";
return View();
}
Tekan CTRL+F5 untuk menjalankan situs. Anda melihat halaman beranda dengan menu utama.
Membuat Model Data
Selanjutnya Anda akan membuat kelas entitas untuk aplikasi Contoso University. Anda akan mulai dengan tiga entitas berikut:
Ada hubungan satu-ke-banyak antara Student
Enrollment
dan entitas, dan ada hubungan satu-ke-banyak antara Course
dan Enrollment
entitas. Dengan kata lain, siswa dapat terdaftar di sejumlah kursus, dan kursus dapat memiliki sejumlah siswa yang terdaftar di dalamnya.
Di bagian berikut, Anda akan membuat kelas untuk masing-masing entitas ini.
Catatan
Jika Anda mencoba mengkompilasi proyek sebelum selesai membuat semua kelas entitas ini, Anda akan mendapatkan kesalahan kompilator.
Entitas Siswa
Di folder Model, buat Student.cs dan ganti kode yang ada dengan kode berikut:
using System;
using System.Collections.Generic;
namespace ContosoUniversity.Models
{
public class Student
{
public int StudentID { 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 StudentID
akan menjadi kolom kunci utama tabel database yang sesuai dengan kelas ini. Secara default, Kerangka Kerja Entitas menginterpretasikan properti yang diberi nama ID
atau nama ID
kelas sebagai kunci utama.
Properti Enrollments
adalah properti navigasi. Properti navigasi menyimpan entitas lain yang terkait dengan entitas ini. Dalam hal ini, Enrollments
properti Student
entitas akan menampung semua entitas yang terkait dengan Student
entitas tersebutEnrollment
. Dengan kata lain, jika baris tertentu Student
dalam database memiliki dua baris terkait Enrollment
(baris yang berisi nilai kunci utama siswa di kolom kunci asing mereka StudentID
), Student
properti navigasi entitas tersebut Enrollments
akan berisi dua Enrollment
entitas tersebut.
Properti navigasi biasanya didefinisikan virtual
sehingga dapat memanfaatkan fungsionalitas Kerangka Kerja Entitas tertentu seperti pemuatan malas. (Pemuatan malas akan dijelaskan nanti, di Tutorial Membaca Data Terkait nanti dalam seri ini.
Jika properti navigasi dapat menampung beberapa entitas (seperti dalam hubungan banyak ke banyak atau satu-ke-banyak), jenisnya harus berupa daftar di mana entri dapat ditambahkan, dihapus, dan diperbarui, seperti ICollection
.
Entitas Pendaftaran
Di folder Model, buat Enrollment.cs dan ganti kode yang ada dengan kode berikut:
namespace ContosoUniversity.Models
{
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 Grade adalah enum. Tanda tanya setelah Grade
deklarasi jenis menunjukkan bahwa Grade
properti dapat diubah ke null. Nilai null berbeda dari nilai nol — null berarti nilai belum diketahui atau belum ditetapkan.
Properti StudentID
adalah kunci asing, dan properti navigasi yang sesuai adalah Student
. Entitas Enrollment
dikaitkan dengan satu Student
entitas, sehingga properti hanya dapat menampung satu Student
entitas (tidak seperti Student.Enrollments
properti navigasi yang Anda lihat sebelumnya, yang dapat menampung beberapa Enrollment
entitas).
Properti CourseID
adalah kunci asing, dan properti navigasi yang sesuai adalah Course
. Entitas Enrollment
dikaitkan dengan satu Course
entitas.
Entitas Kursus
Di folder Model, buat Course.cs, ganti kode yang ada dengan kode berikut:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
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; }
}
}
Properti Enrollments
adalah properti navigasi. Entitas Course
dapat terkait dengan sejumlah Enrollment
entitas.
Kami akan mengatakan lebih lanjut tentang [DatabaseGenerated(DatabaseGeneratedOption. Tidak ada)] atribut dalam tutorial berikutnya. Pada dasarnya, atribut ini memungkinkan Anda memasukkan kunci utama untuk kursus daripada membuat database.
Membuat Konteks Database
Kelas utama yang mengoordinasikan fungsionalitas Kerangka Kerja Entitas untuk model data tertentu adalah kelas konteks database. Anda membuat kelas ini dengan berasal dari kelas System.Data.Entity.DbContext . Dalam kode Anda, Anda menentukan entitas mana yang disertakan dalam model data. Anda juga dapat menyesuaikan perilaku Kerangka Kerja Entitas tertentu. Dalam proyek ini, kelas diberi nama SchoolContext
.
Buat folder bernama DAL (untuk Lapisan Akses Data). Di folder tersebut buat file kelas baru bernama SchoolContext.cs, dan ganti kode yang ada dengan kode berikut:
using ContosoUniversity.Models;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace ContosoUniversity.DAL
{
public class SchoolContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Kode ini membuat properti DbSet untuk setiap set entitas. Dalam terminologi Kerangka Kerja Entitas, kumpulan entitas biasanya sesuai dengan tabel database, dan entitas sesuai dengan baris dalam tabel.
Pernyataan modelBuilder.Conventions.Remove
dalam metode OnModelCreating mencegah nama tabel di-pluralisasi. Jika Anda tidak melakukan ini, tabel yang dihasilkan akan diberi nama Students
, , Courses
dan Enrollments
. Sebagai gantinya, nama tabel akan menjadi Student
, Course
, dan Enrollment
. Pengembang tidak setuju tentang apakah nama tabel harus di-pluralisasi atau tidak. Tutorial ini menggunakan bentuk tunggal, tetapi poin pentingnya adalah Anda dapat memilih formulir mana pun yang Anda sukai dengan menyertakan atau menghilangkan baris kode ini.
LocalDB SQL Server Express
LocalDB adalah versi ringan dari SQL Server Express Database Engine yang dimulai sesuai permintaan dan berjalan dalam mode pengguna. LocalDB berjalan dalam mode eksekusi khusus SQL Server Express yang memungkinkan Anda bekerja dengan database sebagai file .mdf . Biasanya, file database LocalDB disimpan di folder App_Data proyek web. Fitur instans pengguna di SQL Server Express juga memungkinkan Anda untuk bekerja dengan file .mdf , tetapi fitur instans pengguna tidak digunakan lagi; oleh karena itu, LocalDB direkomendasikan untuk bekerja dengan file .mdf .
Biasanya SQL Server Express tidak digunakan untuk aplikasi web produksi. LocalDB khususnya tidak disarankan untuk penggunaan produksi dengan aplikasi web karena tidak dirancang untuk bekerja dengan IIS.
Di Visual Studio 2012 dan versi yang lebih baru, LocalDB diinstal secara default dengan Visual Studio. Di Visual Studio 2010 dan versi yang lebih lama, SQL Server Express (tanpa LocalDB) diinstal secara default dengan Visual Studio; Anda harus menginstalnya secara manual jika Anda menggunakan Visual Studio 2010.
Dalam tutorial ini Anda akan bekerja dengan LocalDB sehingga database dapat disimpan di folder App_Data sebagai file .mdf . Buka file Web.config akar dan tambahkan string koneksi baru ke connectionStrings
koleksi, seperti yang ditunjukkan dalam contoh berikut. (Pastikan Anda memperbarui File Web.config di folder proyek akar. Ada juga file Web.config ada di subfolder Tampilan yang tidak perlu Anda perbarui.)
<add name="SchoolContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ContosoUniversity;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\ContosoUniversity.mdf" providerName="System.Data.SqlClient" />
Secara default, Kerangka Kerja Entitas mencari string koneksi bernama sama DbContext
dengan kelas (SchoolContext
untuk proyek ini). string koneksi yang telah Anda tambahkan menentukan database LocalDB bernama ContosoUniversity.mdf yang terletak di folder App_Data. Untuk informasi selengkapnya, lihat String Koneksi SQL Server untuk aplikasi web ASP.NET.
Anda tidak benar-benar perlu menentukan string koneksi. Jika Anda tidak menyediakan string koneksi, Entity Framework akan membuatnya untuk Anda; namun, database mungkin tidak berada di folder App_data aplikasi Anda. Untuk informasi tentang tempat database akan dibuat, lihat Kode Pertama ke Database Baru.
Koleksi ini connectionStrings
juga memiliki string koneksi bernama DefaultConnection
yang digunakan untuk database keanggotaan. Anda tidak akan menggunakan database keanggotaan dalam tutorial ini. Satu-satunya perbedaan antara dua string koneksi adalah nama database dan nilai atribut nama.
Menyiapkan dan Menjalankan Migrasi Pertama Kode
Ketika Anda pertama kali mulai mengembangkan aplikasi, model data Anda sering berubah, dan setiap kali model mengubahnya tidak sinkron dengan database. Anda dapat mengonfigurasi Kerangka Kerja Entitas untuk secara otomatis menghilangkan dan membuat ulang database setiap kali Anda mengubah model data. Ini bukan masalah di awal pengembangan karena data pengujian mudah dibuat ulang, tetapi setelah Anda menyebarkan ke produksi, Anda biasanya ingin memperbarui skema database tanpa menghilangkan database. Fitur Migrasi memungkinkan Code First memperbarui database tanpa menghilangkan dan membuatnya kembali. Di awal siklus pengembangan proyek baru, Anda mungkin ingin menggunakan DropCreateDatabaseIfModelChanges untuk menghilangkan, membuat ulang, dan menyemai ulang database setiap kali model berubah. Salah satu yang Anda siapkan untuk menyebarkan aplikasi, Anda dapat mengonversi ke pendekatan migrasi. Untuk tutorial ini, Anda hanya akan menggunakan migrasi. Untuk informasi selengkapnya, lihat Seri Screencast Migrasi dan Migrasi Pertama Kode.
Aktifkan Migrasi Pertama Kode
Dari menu Alat, klik Pengelola Paket NuGet lalu Konsol Manajer Paket.
Pada perintah
PM>
masukkan perintah berikut:enable-migrations -contexttypename SchoolContext
Perintah ini membuat folder Migrasi di proyek ContosoUniversity, dan dimasukkan ke dalam folder tersebut file Configuration.cs yang dapat Anda edit untuk mengonfigurasi Migrasi.
Kelas
Configuration
menyertakanSeed
metode yang dipanggil saat database dibuat dan setiap kali diperbarui setelah model data berubah.internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.Models.SchoolContext> { public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(ContosoUniversity.Models.SchoolContext 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" } // ); // } }
Tujuan dari metode ini
Seed
adalah untuk memungkinkan Anda menyisipkan data pengujian ke dalam database setelah Kode Pertama membuatnya atau memperbaruinya.
Menyiapkan Metode Benih
Metode Seed berjalan saat Migrasi Pertama Kode membuat database dan setiap kali memperbarui database ke migrasi terbaru. Tujuan dari metode Seed adalah untuk memungkinkan Anda menyisipkan data ke dalam tabel Anda sebelum aplikasi mengakses database untuk pertama kalinya.
Dalam versi Code First yang lebih lama, sebelum Migrasi dirilis, adalah umum bagi metode untuk Seed
menyisipkan data pengujian, karena dengan setiap perubahan model selama pengembangan database harus dihapus sepenuhnya dan dibuat ulang dari awal. Dengan Migrasi Pertama Kode, data pengujian disimpan setelah perubahan database, jadi termasuk data pengujian dalam metode Seed biasanya tidak diperlukan. Bahkan, Anda tidak ingin Seed
metode menyisipkan data pengujian jika Anda akan menggunakan Migrasi untuk menyebarkan database ke produksi, karena Seed
metode akan berjalan dalam produksi. Dalam hal ini Anda ingin Seed
metode disisipkan ke dalam database hanya data yang ingin Anda sisipkan dalam produksi. Misalnya, Anda mungkin ingin database menyertakan nama departemen aktual dalam Department
tabel saat aplikasi tersedia dalam produksi.
Untuk tutorial ini, Anda akan menggunakan Migrasi untuk penyebaran, tetapi metode Anda Seed
akan tetap menyisipkan data pengujian untuk mempermudah melihat cara kerja fungsionalitas aplikasi tanpa harus menyisipkan banyak data secara manual.
Ganti konten file Configuration.cs dengan kode berikut, yang akan memuat data pengujian ke dalam database baru.
namespace ContosoUniversity.Migrations { using System; using System.Collections.Generic; using System.Data.Entity.Migrations; using System.Linq; using ContosoUniversity.Models; internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.DAL.SchoolContext> { public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(ContosoUniversity.DAL.SchoolContext context) { var students = new List<Student> { new Student { FirstMidName = "Carson", LastName = "Alexander", EnrollmentDate = DateTime.Parse("2010-09-01") }, new Student { FirstMidName = "Meredith", LastName = "Alonso", EnrollmentDate = DateTime.Parse("2012-09-01") }, new Student { FirstMidName = "Arturo", LastName = "Anand", EnrollmentDate = DateTime.Parse("2013-09-01") }, new Student { FirstMidName = "Gytis", LastName = "Barzdukas", EnrollmentDate = DateTime.Parse("2012-09-01") }, new Student { FirstMidName = "Yan", LastName = "Li", EnrollmentDate = DateTime.Parse("2012-09-01") }, new Student { FirstMidName = "Peggy", LastName = "Justice", EnrollmentDate = DateTime.Parse("2011-09-01") }, new Student { FirstMidName = "Laura", LastName = "Norman", EnrollmentDate = DateTime.Parse("2013-09-01") }, new Student { FirstMidName = "Nino", LastName = "Olivetto", EnrollmentDate = DateTime.Parse("2005-08-11") } }; students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, s)); context.SaveChanges(); var courses = new List<Course> { new Course {CourseID = 1050, Title = "Chemistry", Credits = 3, }, new Course {CourseID = 4022, Title = "Microeconomics", Credits = 3, }, new Course {CourseID = 4041, Title = "Macroeconomics", Credits = 3, }, new Course {CourseID = 1045, Title = "Calculus", Credits = 4, }, new Course {CourseID = 3141, Title = "Trigonometry", Credits = 4, }, new Course {CourseID = 2021, Title = "Composition", Credits = 3, }, new Course {CourseID = 2042, Title = "Literature", Credits = 4, } }; courses.ForEach(s => context.Courses.AddOrUpdate(p => p.Title, s)); context.SaveChanges(); var enrollments = new List<Enrollment> { new Enrollment { StudentID = students.Single(s => s.LastName == "Alexander").StudentID, CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID, Grade = Grade.A }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alexander").StudentID, CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID, Grade = Grade.C }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alexander").StudentID, CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alonso").StudentID, CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alonso").StudentID, CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alonso").StudentID, CourseID = courses.Single(c => c.Title == "Composition" ).CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Anand").StudentID, CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID }, new Enrollment { StudentID = students.Single(s => s.LastName == "Anand").StudentID, CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Barzdukas").StudentID, CourseID = courses.Single(c => c.Title == "Chemistry").CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Li").StudentID, CourseID = courses.Single(c => c.Title == "Composition").CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Justice").StudentID, CourseID = courses.Single(c => c.Title == "Literature").CourseID, Grade = Grade.B } }; foreach (Enrollment e in enrollments) { var enrollmentInDataBase = context.Enrollments.Where( s => s.Student.StudentID == e.StudentID && s.Course.CourseID == e.CourseID).SingleOrDefault(); if (enrollmentInDataBase == null) { context.Enrollments.Add(e); } } context.SaveChanges(); } } }
Metode Seed mengambil objek konteks database sebagai parameter input, dan kode dalam metode menggunakan objek tersebut untuk menambahkan entitas baru ke database. Untuk setiap jenis entitas, kode membuat kumpulan entitas baru, menambahkannya ke properti DbSet yang sesuai, lalu menyimpan perubahan ke database. Tidak perlu memanggil metode SaveChanges setelah setiap grup entitas, seperti yang dilakukan di sini, tetapi melakukan itu membantu Anda menemukan sumber masalah jika terjadi pengecualian saat kode menulis ke database.
Beberapa pernyataan yang menyisipkan data menggunakan metode AddOrUpdate untuk melakukan operasi "upsert".
Seed
Karena metode berjalan dengan setiap migrasi, Anda tidak bisa hanya menyisipkan data, karena baris yang coba Anda tambahkan sudah ada setelah migrasi pertama yang membuat database. Operasi "upsert" mencegah kesalahan yang akan terjadi jika Anda mencoba menyisipkan baris yang sudah ada, tetapi mengganti perubahan apa pun pada data yang mungkin telah Anda buat saat menguji aplikasi. Dengan data pengujian dalam beberapa tabel, Anda mungkin tidak ingin hal itu terjadi: dalam beberapa kasus saat Anda mengubah data saat menguji perubahan yang Anda inginkan tetap ada setelah pembaruan database. Dalam hal ini Anda ingin melakukan operasi penyisipan kondisional: sisipkan baris hanya jika belum ada. Metode Seed menggunakan kedua pendekatan.Parameter pertama yang diteruskan ke metode AddOrUpdate menentukan properti yang akan digunakan untuk memeriksa apakah baris sudah ada. Untuk data siswa uji yang Anda berikan,
LastName
properti dapat digunakan untuk tujuan ini karena setiap nama belakang dalam daftar unik:context.Students.AddOrUpdate(p => p.LastName, s)
Kode ini mengasumsikan bahwa nama belakang unik. Jika Anda menambahkan siswa secara manual dengan nama belakang duplikat, Anda akan mendapatkan pengecualian berikut saat berikutnya Anda melakukan migrasi.
Urutan berisi lebih dari satu elemen
Untuk informasi selengkapnya tentang metode ini
AddOrUpdate
, lihat Berhati-hatilah dengan Metode AddOrUpdate EF 4.3 di blog Julie Lerman.Kode yang menambahkan
Enrollment
entitas tidak menggunakanAddOrUpdate
metode . Ini memeriksa apakah entitas sudah ada dan menyisipkan entitas jika tidak ada. Pendekatan ini akan mempertahankan perubahan yang Anda buat pada tingkat pendaftaran saat migrasi berjalan. Kode mengulangi setiap anggotaEnrollment
Daftar dan jika pendaftaran tidak ditemukan dalam database, kode akan menambahkan pendaftaran ke database. Pertama kali Anda memperbarui database, database akan kosong, sehingga akan menambahkan setiap pendaftaran.foreach (Enrollment e in enrollments) { var enrollmentInDataBase = context.Enrollments.Where( s => s.Student.StudentID == e.Student.StudentID && s.Course.CourseID == e.Course.CourseID).SingleOrDefault(); if (enrollmentInDataBase == null) { context.Enrollments.Add(e); } }
Untuk informasi tentang cara men-debug
Seed
metode dan cara menangani data yang berlebihan seperti dua siswa bernama "Alexander Carson", lihat DB Seeding and Debugging Entity Framework (EF) di blog Rick Anderson.Bangun proyek.
Membuat dan Menjalankan Migrasi Pertama
Di jendela Konsol Manajer Paket, masukkan perintah berikut:
add-migration InitialCreate update-database
Perintah
add-migration
menambahkan ke folder Migrasi file [DateStamp]_InitialCreate.cs yang berisi kode yang membuat database. Parameter pertama (InitialCreate)
digunakan untuk nama file dan dapat menjadi apa pun yang Anda inginkan; Anda biasanya memilih kata atau frasa yang meringkas apa yang sedang dilakukan dalam migrasi. Misalnya, Anda mungkin memberi nama migrasi selanjutnya "AddDepartmentTable".Metode
Up
InitialCreate
kelas membuat tabel database yang sesuai dengan kumpulan entitas model data, danDown
metode menghapusnya. Migrasi memanggilUp
metode untuk menerapkan perubahan model data untuk migrasi. Saat Anda memasukkan perintah untuk mengembalikan pembaruan, Migrasi memanggilDown
metode . Kode berikut menunjukkan kontenInitialCreate
file:namespace ContosoUniversity.Migrations { using System; using System.Data.Entity.Migrations; public partial class InitialCreate : DbMigration { public override void Up() { CreateTable( "dbo.Student", c => new { StudentID = c.Int(nullable: false, identity: true), LastName = c.String(), FirstMidName = c.String(), EnrollmentDate = c.DateTime(nullable: false), }) .PrimaryKey(t => t.StudentID); CreateTable( "dbo.Enrollment", c => new { EnrollmentID = c.Int(nullable: false, identity: true), CourseID = c.Int(nullable: false), StudentID = c.Int(nullable: false), Grade = c.Int(), }) .PrimaryKey(t => t.EnrollmentID) .ForeignKey("dbo.Course", t => t.CourseID, cascadeDelete: true) .ForeignKey("dbo.Student", t => t.StudentID, cascadeDelete: true) .Index(t => t.CourseID) .Index(t => t.StudentID); CreateTable( "dbo.Course", c => new { CourseID = c.Int(nullable: false), Title = c.String(), Credits = c.Int(nullable: false), }) .PrimaryKey(t => t.CourseID); } public override void Down() { DropIndex("dbo.Enrollment", new[] { "StudentID" }); DropIndex("dbo.Enrollment", new[] { "CourseID" }); DropForeignKey("dbo.Enrollment", "StudentID", "dbo.Student"); DropForeignKey("dbo.Enrollment", "CourseID", "dbo.Course"); DropTable("dbo.Course"); DropTable("dbo.Enrollment"); DropTable("dbo.Student"); } } }
Perintah
update-database
menjalankanUp
metode untuk membuat database lalu menjalankanSeed
metode untuk mengisi database.
Database SQL Server sekarang telah dibuat untuk model data Anda. Nama database adalah ContosoUniversity, dan file .mdf ada di folder App_Data proyek Anda karena itulah yang Anda tentukan dalam string koneksi Anda.
Anda dapat menggunakan Server Explorer atau SQL Server Object Explorer (SSOX) untuk melihat database di Visual Studio. Untuk tutorial ini, Anda akan menggunakan Server Explorer. Di Visual Studio Express 2012 untuk Web, Server Explorer disebut Database Explorer.
Dari menu Tampilan, klik Penjelajah Server.
Klik ikon Tambahkan Koneksi.
Jika Anda diminta dengan dialog Pilih Sumber Data, klik Microsoft SQL Server, lalu klik Lanjutkan.
Dalam kotak dialog Tambahkan Koneksi , masukkan (localdb)\v11.0 untuk Nama Server. Di bawah Pilih atau masukkan nama database, pilih ContosoUniversity.
Klik OK.
Perluas SchoolContext lalu perluas Tabel.
Klik kanan tabel Siswa dan klik Perlihatkan Data Tabel untuk melihat kolom yang dibuat dan baris yang disisipkan ke dalam tabel.
Membuat Pengontrol dan Tampilan Siswa
Langkah selanjutnya adalah membuat pengontrol dan tampilan MVC ASP.NET dalam aplikasi Anda yang dapat bekerja dengan salah satu tabel ini.
Untuk membuat
Student
pengontrol, klik kanan folder Pengontrol di Penjelajah Solusi, pilih Tambahkan, lalu klik Pengontrol. Dalam kotak dialog Tambahkan Pengontrol , buat pilihan berikut lalu klik Tambahkan:Nama pengontrol: StudentController.
Templat: Pengontrol MVC dengan tindakan dan tampilan baca/tulis, menggunakan Kerangka Kerja Entitas.
Kelas model: Siswa (ContosoUniversity.Models). (Jika Anda tidak melihat opsi ini di daftar drop-down, buat proyek dan coba lagi.)
Kelas konteks data: SchoolContext (ContosoUniversity.Models).
Tampilan: Razor (CSHTML). (Default.)
Visual Studio membuka file Controllers\StudentController.cs . Anda melihat variabel kelas telah dibuat yang membuat instans objek konteks database:
private SchoolContext db = new SchoolContext();
Metode
Index
tindakan mendapatkan daftar siswa dari entitas Siswa yang ditetapkan dengan membacaStudents
properti instans konteks database:public ViewResult Index() { return View(db.Students.ToList()); }
Tampilan Student\Index.cshtml menampilkan daftar ini dalam tabel:
<table> <tr> <th> @Html.DisplayNameFor(model => model.LastName) </th> <th> @Html.DisplayNameFor(model => model.FirstMidName) </th> <th> @Html.DisplayNameFor(model => model.EnrollmentDate) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.LastName) </td> <td> @Html.DisplayFor(modelItem => item.FirstMidName) </td> <td> @Html.DisplayFor(modelItem => item.EnrollmentDate) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) | @Html.ActionLink("Details", "Details", new { id=item.StudentID }) | @Html.ActionLink("Delete", "Delete", new { id=item.StudentID }) </td> </tr> }
Tekan CTRL+F5 untuk menjalankan proyek.
Klik tab Siswa untuk melihat data pengujian yang
Seed
disisipkan metode.
Konvensi
Jumlah kode yang harus Anda tulis agar Kerangka Kerja Entitas dapat membuat database lengkap untuk Anda minimal karena penggunaan konvensi, atau asumsi yang dibuat Kerangka Kerja Entitas. Beberapa dari mereka telah dicatat:
- Bentuk nama kelas entitas yang di-pluralisasi digunakan sebagai nama tabel.
- Nama properti entitas digunakan untuk nama kolom.
- Properti entitas yang diberi nama
ID
atau namaID
kelas dikenali sebagai properti kunci utama.
Anda telah melihat bahwa konvensi dapat ditimpa (misalnya, Anda menentukan bahwa nama tabel tidak boleh di-pluralisasi), dan Anda akan mempelajari selengkapnya tentang konvensi dan cara mengambil alihnya dalam tutorial Membuat Model Data yang Lebih Kompleks nanti dalam seri ini. Untuk informasi selengkapnya, lihat Konvensi Pertama Kode.
Ringkasan
Anda sekarang telah membuat aplikasi sederhana yang menggunakan Kerangka Kerja Entitas dan SQL Server Express untuk menyimpan dan menampilkan data. Dalam tutorial berikut, Anda akan mempelajari cara melakukan operasi CRUD dasar (membuat, membaca, memperbarui, menghapus). Anda dapat meninggalkan umpan balik di bagian bawah halaman ini. Beri tahu kami bagaimana Anda menyukai bagian tutorial ini dan bagaimana kami dapat meningkatkannya.
Tautan ke sumber daya Entity Framework lainnya dapat ditemukan di Peta Konten Akses Data ASP.NET.