Bagikan melalui


Membuat Lapisan Akses Data

oleh Erik Reitan

Seri tutorial ini akan mengajari Anda dasar-dasar membangun aplikasi ASP.NET Web Forms menggunakan ASP.NET 4.5 dan Microsoft Visual Studio Express 2013 untuk Web. Proyek Visual Studio 2013 dengan kode sumber C# tersedia untuk menyertai seri tutorial ini.

Tutorial ini menjelaskan cara membuat, mengakses, dan meninjau data dari database menggunakan ASP.NET Web Forms dan Entity Framework Code First. Tutorial ini dibangun pada tutorial sebelumnya "Buat Proyek" dan merupakan bagian dari seri tutorial Wingtip Toy Store. Setelah menyelesaikan tutorial ini, Anda akan membuat sekelompok kelas akses data yang ada di folder Model proyek.

Yang akan Anda pelajari:

  • Cara membuat model data.
  • Cara menginisialisasi dan menyemai database.
  • Cara memperbarui dan mengonfigurasi aplikasi untuk mendukung database.

Ini adalah fitur yang diperkenalkan dalam tutorial:

  • Kode Kerangka Kerja Entitas Pertama
  • LocalDB
  • Anotasi Data

Membuat Model Data

Entity Framework adalah kerangka kerja pemetaan relasional objek (ORM). Ini memungkinkan Anda bekerja dengan data relasional sebagai objek, menghilangkan sebagian besar kode akses data yang biasanya perlu Anda tulis. Dengan menggunakan Kerangka Kerja Entitas, Anda dapat mengeluarkan kueri menggunakan LINQ, lalu mengambil dan memanipulasi data sebagai objek yang diketik dengan kuat. LINQ menyediakan pola untuk mengkueri dan memperbarui data. Menggunakan Kerangka Kerja Entitas memungkinkan Anda untuk fokus pada pembuatan sisa aplikasi Anda, daripada berfokus pada dasar-dasar akses data. Nanti dalam seri tutorial ini, kami akan menunjukkan kepada Anda cara menggunakan data untuk mengisi kueri navigasi dan produk.

Entity Framework mendukung paradigma pengembangan yang disebut Code First. Code First memungkinkan Anda menentukan model data menggunakan kelas. Kelas adalah konstruksi yang memungkinkan Anda membuat jenis kustom Anda sendiri dengan mengelompokkan variabel jenis, metode, dan peristiwa lainnya. Anda dapat memetakan kelas ke database yang sudah ada atau menggunakannya untuk menghasilkan database. Dalam tutorial ini, Anda akan membuat model data dengan menulis kelas model data. Kemudian, Anda akan membiarkan Entity Framework membuat database dengan cepat dari kelas baru ini.

Anda akan mulai dengan membuat kelas entitas yang menentukan model data untuk aplikasi Formulir Web. Kemudian Anda akan membuat kelas konteks yang mengelola kelas entitas dan menyediakan akses data ke database. Anda juga akan membuat kelas penginisialisasi yang akan Anda gunakan untuk mengisi database.

Kerangka Kerja dan Referensi Entitas

Secara default, Kerangka Kerja Entitas disertakan saat Anda membuat aplikasi web ASP.NET baru menggunakan templat Formulir Web . Entity Framework dapat diinstal, dihapus, dan diperbarui sebagai paket NuGet.

Paket NuGet ini mencakup rakitan runtime berikut dalam proyek Anda:

  • EntityFramework.dll – Semua kode runtime umum yang digunakan oleh Kerangka Kerja Entitas
  • EntityFramework.SqlServer.dll – Penyedia Microsoft SQL Server untuk Entity Framework

Kelas Entitas

Kelas yang Anda buat untuk menentukan skema data disebut kelas entitas. Jika Anda baru menggunakan desain database, anggap kelas entitas sebagai definisi tabel database. Setiap properti di kelas menentukan kolom dalam tabel database. Kelas-kelas ini menyediakan antarmuka relasional objek yang ringan antara kode berorientasi objek dan struktur tabel relasional database.

Dalam tutorial ini, Anda akan memulai dengan menambahkan kelas entitas sederhana yang mewakili skema untuk produk dan kategori. Kelas produk akan berisi definisi untuk setiap produk. Nama masing-masing anggota kelas produk akan menjadi ProductID, , ProductName, Description, ImagePathUnitPrice, CategoryID, dan Category. Kelas kategori akan berisi definisi untuk setiap kategori yang dapat dimiliki produk, seperti Mobil, Perahu, atau Pesawat. Nama masing-masing anggota kelas kategori akan menjadi CategoryID, , CategoryNameDescription, dan Products. Setiap produk akan termasuk dalam salah satu kategori. Kelas entitas ini akan ditambahkan ke folder Model proyek yang ada.

  1. Di Penjelajah Solusi, klik kanan folder Model lalu pilih Tambahkan ->Item Baru.

    Cuplikan layar jendela Penjelajah Solusi dengan folder Model disorot dan menu dropdown Tambahkan dan Item Baru dipilih.

    Kotak dialog Tambahkan Item Baru ditampilkan.

  2. Di bawah Visual C# dari panel Terinstal di sebelah kiri, pilih Kode.

    Cuplikan layar jendela Tambahkan Item Baru memperlihatkan panel Terinstal di sebelah kiri dengan Visual C# terbuka dan Kode dipilih.

  3. Pilih Kelas dari panel tengah dan beri nama kelas baru ini Product.cs.

  4. Klik Tambahkan.
    File kelas baru ditampilkan di editor.

  5. Ganti kode default dengan kode berikut:

    using System.ComponentModel.DataAnnotations;
    
    namespace WingtipToys.Models
    {
        public class Product
        {
            [ScaffoldColumn(false)]
            public int ProductID { get; set; }
    
            [Required, StringLength(100), Display(Name = "Name")]
            public string ProductName { get; set; }
    
            [Required, StringLength(10000), Display(Name = "Product Description"), DataType(DataType.MultilineText)]
            public string Description { get; set; }
    
            public string ImagePath { get; set; }
    
            [Display(Name = "Price")]
            public double? UnitPrice { get; set; }
    
            public int? CategoryID { get; set; }
    
            public virtual Category Category { get; set; }
        }
    }
    
  6. Buat kelas lain dengan mengulangi langkah 1 hingga 4, namun, beri nama kelas baru Category.cs dan ganti kode default dengan kode berikut:

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace WingtipToys.Models
    {
        public class Category
        {
            [ScaffoldColumn(false)]
            public int CategoryID { get; set; }
    
            [Required, StringLength(100), Display(Name = "Name")]
            public string CategoryName { get; set; }
    
            [Display(Name = "Product Description")]
            public string Description { get; set; }
    
            public virtual ICollection<Product> Products { get; set; }
        }
    }
    

Seperti yang disebutkan sebelumnya, Category kelas mewakili jenis produk yang dirancang untuk dijual aplikasi (seperti "Mobil", "Perahu", "Roket", dan sebagainya ), dan Product kelas mewakili produk individu (mainan) dalam database. Setiap instans Product objek akan sesuai dengan baris dalam tabel database relasional, dan setiap properti kelas Produk akan memetakan ke kolom dalam tabel database relasional. Nanti dalam tutorial ini, Anda akan meninjau data produk yang terkandung dalam database.

Anotasi Data

Anda mungkin telah memperhatikan bahwa anggota kelas tertentu memiliki atribut yang menentukan detail tentang anggota, seperti [ScaffoldColumn(false)]. Ini adalah anotasi data. Atribut anotasi data dapat menjelaskan cara memvalidasi input pengguna untuk anggota tersebut, untuk menentukan pemformatannya, dan menentukan bagaimana modelnya saat database dibuat.

Kelas Konteks

Untuk mulai menggunakan kelas untuk akses data, Anda harus menentukan kelas konteks. Seperti disebutkan sebelumnya, kelas konteks mengelola kelas entitas (seperti Product kelas dan Category kelas) dan menyediakan akses data ke database.

Prosedur ini menambahkan kelas konteks C# baru ke folder Model .

  1. Klik kanan folder Model lalu pilih Tambahkan ->Item Baru.
    Kotak dialog Tambahkan Item Baru ditampilkan.

  2. Pilih Kelas dari panel tengah, beri nama ProductContext.cs dan klik Tambahkan.

  3. Ganti kode default yang terkandung di kelas dengan kode berikut:

    using System.Data.Entity;
    namespace WingtipToys.Models
    {
        public class ProductContext : DbContext
        {
            public ProductContext() : base("WingtipToys")
            {
            }
            public DbSet<Category> Categories { get; set; }
            public DbSet<Product> Products { get; set; }
        }
    }
    

Kode ini menambahkan System.Data.Entity namespace layanan sehingga Anda memiliki akses ke semua fungsi inti Kerangka Kerja Entitas, yang mencakup kemampuan untuk mengkueri, menyisipkan, memperbarui, dan menghapus data dengan bekerja dengan objek yang ditik dengan kuat.

Kelas mewakili ProductContext konteks database produk Entity Framework, yang menangani pengambilan, penyimpanan, dan pembaruan Product instans kelas dalam database. Kelas ProductContext ini berasal dari DbContext kelas dasar yang disediakan oleh Entity Framework.

Kelas Initializer

Anda harus menjalankan beberapa logika kustom untuk menginisialisasi database saat pertama kali konteks digunakan. Ini akan memungkinkan data benih ditambahkan ke database sehingga Anda dapat segera menampilkan produk dan kategori.

Prosedur ini menambahkan kelas penginisialisasi C# baru ke folder Model .

  1. Buat yang lain Class di folder Model dan beri nama ProductDatabaseInitializer.cs.

  2. Ganti kode default yang terkandung di kelas dengan kode berikut:

    using System.Collections.Generic;
    using System.Data.Entity;
    
    namespace WingtipToys.Models
    {
      public class ProductDatabaseInitializer : DropCreateDatabaseIfModelChanges<ProductContext>
      {
        protected override void Seed(ProductContext context)
        {
          GetCategories().ForEach(c => context.Categories.Add(c));
          GetProducts().ForEach(p => context.Products.Add(p));
        }
    
        private static List<Category> GetCategories()
        {
          var categories = new List<Category> {
                    new Category
                    {
                        CategoryID = 1,
                        CategoryName = "Cars"
                    },
                    new Category
                    {
                        CategoryID = 2,
                        CategoryName = "Planes"
                    },
                    new Category
                    {
                        CategoryID = 3,
                        CategoryName = "Trucks"
                    },
                    new Category
                    {
                        CategoryID = 4,
                        CategoryName = "Boats"
                    },
                    new Category
                    {
                        CategoryID = 5,
                        CategoryName = "Rockets"
                    },
                };
    
          return categories;
        }
    
        private static List<Product> GetProducts()
        {
          var products = new List<Product> {
                    new Product
                    {
                        ProductID = 1,
                        ProductName = "Convertible Car",
                        Description = "This convertible car is fast! The engine is powered by a neutrino based battery (not included)." + 
                                      "Power it up and let it go!", 
                        ImagePath="carconvert.png",
                        UnitPrice = 22.50,
                        CategoryID = 1
                   },
                    new Product 
                    {
                        ProductID = 2,
                        ProductName = "Old-time Car",
                        Description = "There's nothing old about this toy car, except it's looks. Compatible with other old toy cars.",
                        ImagePath="carearly.png",
                        UnitPrice = 15.95,
                         CategoryID = 1
                   },
                    new Product
                    {
                        ProductID = 3,
                        ProductName = "Fast Car",
                        Description = "Yes this car is fast, but it also floats in water.",
                        ImagePath="carfast.png",
                        UnitPrice = 32.99,
                        CategoryID = 1
                    },
                    new Product
                    {
                        ProductID = 4,
                        ProductName = "Super Fast Car",
                        Description = "Use this super fast car to entertain guests. Lights and doors work!",
                        ImagePath="carfaster.png",
                        UnitPrice = 8.95,
                        CategoryID = 1
                    },
                    new Product
                    {
                        ProductID = 5,
                        ProductName = "Old Style Racer",
                        Description = "This old style racer can fly (with user assistance). Gravity controls flight duration." + 
                                      "No batteries required.",
                        ImagePath="carracer.png",
                        UnitPrice = 34.95,
                        CategoryID = 1
                    },
                    new Product
                    {
                        ProductID = 6,
                        ProductName = "Ace Plane",
                        Description = "Authentic airplane toy. Features realistic color and details.",
                        ImagePath="planeace.png",
                        UnitPrice = 95.00,
                        CategoryID = 2
                    },
                    new Product
                    {
                        ProductID = 7,
                        ProductName = "Glider",
                        Description = "This fun glider is made from real balsa wood. Some assembly required.",
                        ImagePath="planeglider.png",
                        UnitPrice = 4.95,
                        CategoryID = 2
                    },
                    new Product
                    {
                        ProductID = 8,
                        ProductName = "Paper Plane",
                        Description = "This paper plane is like no other paper plane. Some folding required.",
                        ImagePath="planepaper.png",
                        UnitPrice = 2.95,
                        CategoryID = 2
                    },
                    new Product
                    {
                        ProductID = 9,
                        ProductName = "Propeller Plane",
                        Description = "Rubber band powered plane features two wheels.",
                        ImagePath="planeprop.png",
                        UnitPrice = 32.95,
                        CategoryID = 2
                    },
                    new Product
                    {
                        ProductID = 10,
                        ProductName = "Early Truck",
                        Description = "This toy truck has a real gas powered engine. Requires regular tune ups.",
                        ImagePath="truckearly.png",
                        UnitPrice = 15.00,
                        CategoryID = 3
                    },
                    new Product
                    {
                        ProductID = 11,
                        ProductName = "Fire Truck",
                        Description = "You will have endless fun with this one quarter sized fire truck.",
                        ImagePath="truckfire.png",
                        UnitPrice = 26.00,
                        CategoryID = 3
                    },
                    new Product
                    {
                        ProductID = 12,
                        ProductName = "Big Truck",
                        Description = "This fun toy truck can be used to tow other trucks that are not as big.",
                        ImagePath="truckbig.png",
                        UnitPrice = 29.00,
                        CategoryID = 3
                    },
                    new Product
                    {
                        ProductID = 13,
                        ProductName = "Big Ship",
                        Description = "Is it a boat or a ship. Let this floating vehicle decide by using its " + 
                                      "artifically intelligent computer brain!",
                        ImagePath="boatbig.png",
                        UnitPrice = 95.00,
                        CategoryID = 4
                    },
                    new Product
                    {
                        ProductID = 14,
                        ProductName = "Paper Boat",
                        Description = "Floating fun for all! This toy boat can be assembled in seconds. Floats for minutes!" + 
                                      "Some folding required.",
                        ImagePath="boatpaper.png",
                        UnitPrice = 4.95,
                        CategoryID = 4
                    },
                    new Product
                    {
                        ProductID = 15,
                        ProductName = "Sail Boat",
                        Description = "Put this fun toy sail boat in the water and let it go!",
                        ImagePath="boatsail.png",
                        UnitPrice = 42.95,
                        CategoryID = 4
                    },
                    new Product
                    {
                        ProductID = 16,
                        ProductName = "Rocket",
                        Description = "This fun rocket will travel up to a height of 200 feet.",
                        ImagePath="rocket.png",
                        UnitPrice = 122.95,
                        CategoryID = 5
                    }
                };
    
          return products;
        }
      }
    }
    

Seperti yang Anda lihat dari kode di atas, ketika database dibuat dan diinisialisasi, Seed properti ditimpa dan diatur. Seed Saat properti diatur, nilai dari kategori dan produk digunakan untuk mengisi database. Jika Anda mencoba memperbarui data seed dengan memodifikasi kode di atas setelah database dibuat, Anda tidak akan melihat pembaruan apa pun saat menjalankan aplikasi Web. Alasannya adalah kode di atas menggunakan implementasi DropCreateDatabaseIfModelChanges kelas untuk mengenali apakah model (skema) telah berubah sebelum mengatur ulang data benih. Jika tidak ada perubahan yang dilakukan pada Category kelas entitas dan Product , database tidak akan diinisialisasi ulang dengan data nilai awal.

Catatan

Jika Anda ingin database dibuat ulang setiap kali Anda menjalankan aplikasi, Anda dapat menggunakan DropCreateDatabaseAlways kelas alih-alih DropCreateDatabaseIfModelChanges kelas . Namun untuk seri tutorial ini, gunakan DropCreateDatabaseIfModelChanges kelas .

Pada titik ini dalam tutorial ini, Anda akan memiliki folder Model dengan empat kelas baru dan satu kelas default:

Membuat Lapisan Akses Data - Folder Model

Mengonfigurasi Aplikasi untuk Menggunakan Model Data

Sekarang setelah Anda membuat kelas yang mewakili data, Anda harus mengonfigurasi aplikasi untuk menggunakan kelas . Dalam file Global.asax , Anda menambahkan kode yang menginisialisasi model. Dalam file Web.config Anda menambahkan informasi yang memberi tahu aplikasi database apa yang akan Anda gunakan untuk menyimpan data yang diwakili oleh kelas data baru. File Global.asax dapat digunakan untuk menangani peristiwa atau metode aplikasi. File Web.config memungkinkan Anda mengontrol konfigurasi aplikasi web ASP.NET Anda.

Memperbarui file Global.asax

Untuk menginisialisasi model data saat aplikasi dimulai, Anda akan memperbarui Application_Start handler dalam file Global.asax.cs .

Catatan

Di Penjelajah Solusi, Anda dapat memilih file Global.asax atau file Global.asax.cs untuk mengedit file Global.asax.cs .

  1. Tambahkan kode berikut yang disorot dengan warna kuning ke Application_Start metode dalam file Global.asax.cs .

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Optimization;
    using System.Web.Routing;
    using System.Web.Security;
    using System.Web.SessionState;
    using System.Data.Entity;
    using WingtipToys.Models;
    
    namespace WingtipToys
    {
        public class Global : HttpApplication
        {
            void Application_Start(object sender, EventArgs e)
            {
                // Code that runs on application startup
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
    
                // Initialize the product database.
                Database.SetInitializer(new ProductDatabaseInitializer());
            }
        }
    }
    

Catatan

Browser Anda harus mendukung HTML5 untuk melihat kode yang disorot dengan warna kuning saat melihat seri tutorial ini di browser.

Seperti yang ditunjukkan pada kode di atas, ketika aplikasi dimulai, aplikasi menentukan penginisialisasi yang akan berjalan selama pertama kali data diakses. Dua namespace tambahan diperlukan untuk mengakses Database objek dan ProductDatabaseInitializer objek .

Mengubah File Web.Config

Meskipun Kode Kerangka Kerja Entitas Pertama akan menghasilkan database untuk Anda di lokasi default ketika database diisi dengan data benih, menambahkan informasi koneksi Anda sendiri ke aplikasi Anda memberi Anda kontrol atas lokasi database. Anda menentukan koneksi database ini menggunakan string koneksi dalam file Web.config aplikasi di akar proyek. Dengan menambahkan string koneksi baru, Anda dapat mengarahkan lokasi database (wingtiptoys.mdf) yang akan dibangun di direktori data aplikasi (App_Data), bukan lokasi defaultnya. Melakukan perubahan ini akan memungkinkan Anda untuk menemukan dan memeriksa file database nanti dalam tutorial ini.

  1. Di Penjelajah Solusi, temukan dan buka file Web.config .

  2. Tambahkan string koneksi yang disorot dengan warna kuning ke <connectionStrings> bagian file Web.config sebagai berikut:

    <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-WingtipToys-20131119102907.mdf;Initial Catalog=aspnet-WingtipToys-20131119102907;Integrated Security=True"
    providerName="System.Data.SqlClient" />
    <add name="WingtipToys"
    connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\wingtiptoys.mdf;Integrated Security=True"
    providerName="System.Data.SqlClient" />
    </connectionStrings>
    

Ketika aplikasi dijalankan untuk pertama kalinya, aplikasi akan membangun database di lokasi yang ditentukan oleh string koneksi. Tetapi sebelum menjalankan aplikasi, mari kita bangun terlebih dahulu.

Membangun Aplikasi

Untuk memastikan bahwa semua kelas dan perubahan pada aplikasi Web Anda berfungsi, Anda harus membangun aplikasi.

  1. Dari menu Debug , pilih Bangun WingtipToys.
    Jendela Output ditampilkan, dan jika semuanya berjalan dengan baik, Anda akan melihat pesan yang berhasil .

    Membuat Lapisan Akses Data - Output Windows

Jika Anda mengalami kesalahan, periksa kembali langkah-langkah di atas. Informasi di jendela Output akan menunjukkan file mana yang mengalami masalah dan di mana dalam file diperlukan perubahan. Informasi ini akan memungkinkan Anda menentukan bagian apa dari langkah-langkah di atas yang perlu ditinjau dan diperbaiki dalam proyek Anda.

Ringkasan

Dalam tutorial seri ini Anda telah membuat model data, serta, menambahkan kode yang akan digunakan untuk menginisialisasi dan menyemai database. Anda juga telah mengonfigurasi aplikasi untuk menggunakan model data saat aplikasi dijalankan.

Dalam tutorial berikutnya, Anda akan memperbarui UI, menambahkan navigasi, dan mengambil data dari database. Ini akan mengakibatkan database dibuat secara otomatis berdasarkan kelas entitas yang Anda buat dalam tutorial ini.

Sumber Daya Tambahan

Gambaran Umum Entity Framework
Panduan Pemula untuk Kerangka Kerja Entitas ADO.NET
Pengembangan Pertama Kode dengan Entity FrameworkCode First Relationships Fluent API
Anotasi Data Pertama Kode
Peningkatan Produktivitas untuk Kerangka Kerja Entitas