Bagikan melalui


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.

Students_Index_page

Cuplikan layar yang memperlihatkan contoh halaman pencarian Siswa aplikasi web Contoso University dan halaman Buat Siswa Baru.

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).

New_project_dialog_box

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.

Project_template_options

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>&copy; @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.

Contoso_University_home_page

Membuat Model Data

Selanjutnya Anda akan membuat kelas entitas untuk aplikasi Contoso University. Anda akan mulai dengan tiga entitas berikut:

Class_diagram

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

Student_entity

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

Enrollment_entity

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

Course_entity

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, , Coursesdan 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

  1. Dari menu Alat, klik Pengelola Paket NuGet lalu Konsol Manajer Paket.

    Selecting_Package_Manager_Console

  2. Pada perintah PM> masukkan perintah berikut:

    enable-migrations -contexttypename SchoolContext
    

    perintah enable-migrations

    Perintah ini membuat folder Migrasi di proyek ContosoUniversity, dan dimasukkan ke dalam folder tersebut file Configuration.cs yang dapat Anda edit untuk mengonfigurasi Migrasi.

    Folder migrasi

    Kelas Configuration menyertakan Seed 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.

  1. 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 menggunakan AddOrUpdate 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 anggota EnrollmentDaftar 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.

  2. Bangun proyek.

Membuat dan Menjalankan Migrasi Pertama

  1. Di jendela Konsol Manajer Paket, masukkan perintah berikut:

    add-migration InitialCreate
    update-database
    

    Cuplikan layar yang memperlihatkan jendela Konsol Manajer Paket. Perintah menambahkan migrasi tanda hubung garis bawah Buat Awal dan perbarui database tanda hubung disorot.

    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".

    Folder migrasi dengan migrasi awal

    Metode Up InitialCreate kelas membuat tabel database yang sesuai dengan kumpulan entitas model data, dan Down metode menghapusnya. Migrasi memanggil Up metode untuk menerapkan perubahan model data untuk migrasi. Saat Anda memasukkan perintah untuk mengembalikan pembaruan, Migrasi memanggil Down metode . Kode berikut menunjukkan konten InitialCreate 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 menjalankan Up metode untuk membuat database lalu menjalankan Seed 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.

  1. Dari menu Tampilan, klik Penjelajah Server.

  2. Klik ikon Tambahkan Koneksi.

    Cuplikan layar yang memperlihatkan jendela Database Explorer. Ikon Tambahkan Koneksi disorot.

  3. Jika Anda diminta dengan dialog Pilih Sumber Data, klik Microsoft SQL Server, lalu klik Lanjutkan.

    Cuplikan layar yang memperlihatkan kotak dialog Pilih Sumber Data. Sumber data Microsoft S Q L Server dipilih.

  4. Dalam kotak dialog Tambahkan Koneksi , masukkan (localdb)\v11.0 untuk Nama Server. Di bawah Pilih atau masukkan nama database, pilih ContosoUniversity.

    Cuplikan layar yang memperlihatkan kotak dialog Tambahkan Koneksi. Contoh Nama server dan database Contoso University disorot.

  5. Klik OK.

  6. Perluas SchoolContext lalu perluas Tabel.

    Cuplikan layar yang memperlihatkan halaman Server Explorer. Tab Konteks dan Tabel Sekolah diperluas.

  7. Klik kanan tabel Siswa dan klik Perlihatkan Data Tabel untuk melihat kolom yang dibuat dan baris yang disisipkan ke dalam tabel.

    Tabel siswa

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.

  1. 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.)

      Add_Controller_dialog_box_for_Student_controller

  2. 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 membaca Students 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>
    }
    
  3. Tekan CTRL+F5 untuk menjalankan proyek.

    Klik tab Siswa untuk melihat data pengujian yang Seed disisipkan metode.

    Halaman Indeks Siswa

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 nama ID 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.