Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
oleh Tom Dykstra
Seri tutorial ini dibangun pada aplikasi web Contoso University yang dibuat oleh seri tutorial Memulai Entity Framework 4.0 . Jika Anda tidak menyelesaikan tutorial sebelumnya, sebagai titik awal untuk tutorial ini, Anda dapat mengunduh aplikasi yang akan Anda buat. Anda juga dapat mengunduh aplikasi yang dibuat oleh seri tutorial lengkap.
Aplikasi web sampel Contoso University menunjukkan cara membuat aplikasi ASP.NET Web Forms menggunakan Entity Framework 4.0 dan Visual Studio 2010. Aplikasi sampel adalah situs web untuk Contoso University fiktif. Ini termasuk fungsionalitas seperti penerimaan siswa, pembuatan kursus, dan tugas instruktur.
Tutorial menunjukkan contoh dalam C#. Sampel yang dapat diunduh berisi kode di C# dan Visual Basic.
Database Pertama
Ada tiga cara Anda dapat bekerja dengan data dalam Kerangka Kerja Entitas: Database Pertama, Model Pertama, dan Kode Pertama. Tutorial ini untuk Database 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.
Formulir Web
Seperti seri Memulai, seri tutorial ini menggunakan model ASP.NET Web Forms dan mengasumsikan Anda tahu cara bekerja dengan ASP.NET Web Forms di Visual Studio. Jika tidak, lihat Mulai menggunakan Formulir Web ASP.NET 4.5. Jika Anda lebih suka bekerja dengan kerangka kerja MVC ASP.NET, lihat Memulai Kerangka Kerja Entitas menggunakan ASP.NET MVC.
Versi perangkat lunak
Ditampilkan dalam tutorial Juga bekerja dengan Windows 7 Windows 8 Visual Studio 2010 Visual Studio 2010 Express untuk Web. Tutorial belum diuji dengan versi Visual Studio yang lebih baru. Ada banyak perbedaan dalam pilihan menu, kotak dialog, dan templat. .NET 4 .NET 4.5 kompatibel mundur dengan .NET 4, tetapi tutorial belum diuji dengan .NET 4.5. Kerangka Kerja Entitas 4 Tutorial belum diuji dengan versi Kerangka Kerja Entitas yang lebih baru. Dimulai dengan Entity Framework 5, EF menggunakan secara default DbContext API
yang diperkenalkan dengan EF 4.1. Kontrol EntityDataSource dirancang untuk menggunakanObjectContext
API. Untuk informasi tentang cara menggunakan kontrol EntityDataSource denganDbContext
API, lihat posting blog ini.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.
Kontrol ini EntityDataSource
memungkinkan Anda membuat aplikasi dengan sangat cepat, tetapi biasanya mengharuskan Anda untuk menyimpan sejumlah besar logika bisnis dan logika akses data di halaman .aspx Anda. Jika Anda mengharapkan aplikasi Anda tumbuh dalam kompleksitas dan memerlukan pemeliharaan yang sedang berlangsung, Anda dapat menginvestasikan lebih banyak waktu pengembangan di muka untuk membuat struktur aplikasi n-tingkat atau berlapis yang lebih dapat dipertahankan. Untuk menerapkan arsitektur ini, Anda memisahkan lapisan presentasi dari lapisan logika bisnis (BLL) dan lapisan akses data (DAL). Salah satu cara untuk mengimplementasikan struktur ini adalah dengan menggunakan ObjectDataSource
kontrol alih-alih EntityDataSource
kontrol. Saat Anda menggunakan ObjectDataSource
kontrol, Anda menerapkan kode akses data Anda sendiri lalu memanggilnya di halaman .aspx menggunakan kontrol yang memiliki banyak fitur yang sama dengan kontrol sumber data lainnya. Ini memungkinkan Anda menggabungkan keuntungan dari pendekatan n-tingkat dengan manfaat menggunakan kontrol Formulir Web untuk akses data.
Kontrol ini ObjectDataSource
juga memberi Anda lebih banyak fleksibilitas dengan cara lain. Karena Anda menulis kode akses data Anda sendiri, lebih mudah untuk melakukan lebih dari sekadar membaca, menyisipkan, memperbarui, atau menghapus jenis entitas tertentu, yang merupakan tugas yang EntityDataSource
dirancang untuk dilakukan kontrol. Misalnya, Anda dapat melakukan pengelogan setiap kali entitas diperbarui, mengarsipkan data setiap kali entitas dihapus, atau secara otomatis memeriksa dan memperbarui data terkait sesuai kebutuhan saat menyisipkan baris dengan nilai kunci asing.
Kelas Logika dan Repositori Bisnis
Kontrol ObjectDataSource
bekerja dengan memanggil kelas yang Anda buat. Kelas ini mencakup metode yang mengambil dan memperbarui data, dan Anda memberikan nama metode tersebut ke ObjectDataSource
kontrol dalam markup. Selama penyajian atau pemrosesan postback, ObjectDataSource
memanggil metode yang telah Anda tentukan.
Selain operasi CRUD dasar, kelas yang Anda buat untuk digunakan dengan ObjectDataSource
kontrol mungkin perlu menjalankan logika bisnis saat ObjectDataSource
membaca atau memperbarui data. Misalnya, ketika Anda memperbarui departemen, Anda mungkin perlu memvalidasi bahwa tidak ada departemen lain yang memiliki administrator yang sama karena satu orang tidak dapat menjadi administrator lebih dari satu departemen.
Dalam beberapa ObjectDataSource
dokumentasi, seperti gambaran umum Kelas ObjectDataSource, kontrol memanggil kelas yang disebut sebagai objek bisnis yang menyertakan logika bisnis dan logika akses data. Dalam tutorial ini Anda akan membuat kelas terpisah untuk logika bisnis dan untuk logika akses data. Kelas yang merangkum logika akses data disebut repositori. Kelas logika bisnis mencakup metode logika bisnis dan metode akses data, tetapi metode akses data memanggil repositori untuk melakukan tugas akses data.
Anda juga akan membuat lapisan abstraksi antara BLL dan DAL Anda yang memfasilitasi pengujian unit otomatis BLL. Lapisan abstraksi ini diimplementasikan dengan membuat antarmuka dan menggunakan antarmuka saat Anda membuat instans repositori di kelas logika bisnis. Ini memungkinkan Anda untuk menyediakan kelas logika bisnis dengan referensi ke objek apa pun yang mengimplementasikan antarmuka repositori. Untuk operasi normal, Anda menyediakan objek repositori yang berfungsi dengan Kerangka Kerja Entitas. Untuk pengujian, Anda menyediakan objek repositori yang berfungsi dengan data yang disimpan dengan cara yang dapat Anda manipulasi dengan mudah, seperti variabel kelas yang didefinisikan sebagai koleksi.
Ilustrasi berikut menunjukkan perbedaan antara kelas logika bisnis yang menyertakan logika akses data tanpa repositori dan yang menggunakan repositori.
Anda akan mulai dengan membuat halaman web di mana ObjectDataSource
kontrol terikat langsung ke repositori karena hanya melakukan tugas akses data dasar. Dalam tutorial berikutnya Anda akan membuat kelas logika bisnis dengan logika validasi dan mengikat kontrol ke kelas tersebut ObjectDataSource
alih-alih ke kelas repositori. Anda juga akan membuat pengujian unit untuk logika validasi. Dalam tutorial ketiga dalam seri ini Anda akan menambahkan fungsi pengurutan dan pemfilteran ke aplikasi.
Halaman yang Anda buat dalam tutorial ini berfungsi dengan Departments
kumpulan entitas model data yang Anda buat dalam seri tutorial Memulai.
Memperbarui Database dan Model Data
Anda akan memulai tutorial ini dengan membuat dua perubahan pada database, yang keduanya memerlukan perubahan yang sesuai dengan model data yang Anda buat di tutorial Memulai Kerangka Kerja Entitas dan Formulir Web . Dalam salah satu tutorial tersebut, Anda membuat perubahan dalam perancang secara manual untuk menyinkronkan model data dengan database setelah perubahan database. Dalam tutorial ini, Anda akan menggunakan alat Update Model From Database desainer untuk memperbarui model data secara otomatis.
Menambahkan Hubungan ke Database
Di Visual Studio, buka aplikasi web Contoso University yang Anda buat di seri tutorial Memulai Kerangka Kerja Entitas dan Formulir Web , lalu buka SchoolDiagram
diagram database.
Jika Anda melihat Department
tabel dalam diagram database, Anda akan melihat bahwa tabel tersebut memiliki Administrator
kolom. Kolom ini adalah kunci asing untuk Person
tabel, tetapi tidak ada hubungan kunci asing yang ditentukan dalam database. Anda perlu membuat hubungan dan memperbarui model data sehingga Kerangka Kerja Entitas dapat menangani hubungan ini secara otomatis.
Dalam diagram database, klik Department
kanan tabel, dan pilih Hubungan.
Dalam kotak Hubungan Kunci Asing klik Tambahkan, lalu klik elipsis untuk Spesifikasi Tabel dan Kolom.
Dalam kotak dialog Tabel dan Kolom , atur tabel dan bidang kunci utama ke Person
dan PersonID
, dan atur tabel dan bidang kunci asing ke Department
dan Administrator
. (Ketika Anda melakukan ini, nama hubungan akan berubah dari FK_Department_Department
ke FK_Department_Person
.)
Klik OK dalam kotak Tabel dan Kolom , klik Tutup dalam kotak Hubungan Kunci Asing , dan simpan perubahan. Jika Anda ditanya apakah Anda ingin menyimpan Person
tabel dan Department
, klik Ya.
Catatan
Jika Anda telah menghapus Person
baris yang sesuai dengan data yang sudah ada di Administrator
kolom, Anda tidak akan dapat menyimpan perubahan ini. Dalam hal ini, gunakan editor tabel di Server Explorer untuk memastikan bahwa Administrator
nilai di setiap Department
baris berisi ID rekaman yang benar-benar ada dalam Person
tabel.
Setelah menyimpan perubahan, Anda tidak akan dapat menghapus baris dari tabel jika orang tersebut Person
adalah administrator departemen. Dalam aplikasi produksi, Anda akan memberikan pesan kesalahan tertentu ketika batasan database mencegah penghapusan, atau Anda akan menentukan penghapusan berskala. Untuk contoh cara menentukan penghapusan berskala, lihat Kerangka Kerja Entitas dan ASP.NET - Memulai Bagian 2.
Menambahkan Tampilan ke Database
Di halaman Departments.aspx baru yang akan Anda buat, Anda ingin memberikan daftar drop-down instruktur, dengan nama dalam format "terakhir, pertama" sehingga pengguna dapat memilih administrator departemen. Untuk mempermudah melakukannya, Anda akan membuat tampilan di database. Tampilan hanya akan terdiri dari data yang diperlukan oleh daftar drop-down: nama lengkap (diformat dengan benar) dan kunci rekaman.
Di Penjelajah Server, perluas School.mdf, klik kanan folder Tampilan , dan pilih Tambahkan Tampilan Baru.
Klik Tutup saat kotak dialog Tambahkan Tabel muncul, dan tempelkan pernyataan SQL berikut ini ke panel SQL:
SELECT LastName + ',' + FirstName AS FullName, PersonID
FROM dbo.Person
WHERE (HireDate IS NOT NULL)
Simpan tampilan sebagai vInstructorName
.
Memperbarui Model Data
Di folder DAL , buka file SchoolModel.edmx , klik kanan permukaan desain, dan pilih Perbarui Model dari Database.
Dalam kotak dialog Pilih Objek Database Anda , pilih tab Tambahkan dan pilih tampilan yang baru saja Anda buat.
Klik Selesai.
Dalam perancang, Anda melihat bahwa alat ini membuat vInstructorName
entitas dan hubungan baru antara Department
entitas dan Person
.
Catatan
Di jendela Output dan Daftar Kesalahan , Anda mungkin melihat pesan peringatan yang memberi tahu Anda bahwa alat secara otomatis membuat kunci primer untuk tampilan baru vInstructorName
. Ini adalah perilaku yang diharapkan.
Ketika Anda merujuk ke entitas baru vInstructorName
dalam kode, Anda tidak ingin menggunakan konvensi database awalan huruf kecil "v" ke dalamnya. Oleh karena itu, Anda akan mengganti nama entitas dan entitas yang ditetapkan dalam model.
Buka Browser Model. Anda melihat vInstructorName
terdaftar sebagai jenis entitas dan tampilan.
Di bawah SchoolModel (tidak SchoolModel.Store), klik kanan vInstructorName dan pilih Properti. Di jendela Properti , ubah properti Nama menjadi "InstructorName" dan ubah properti Nama Set Entitas menjadi "InstructorNames".
Simpan dan tutup model data, lalu bangun kembali proyek.
Menggunakan Kelas Repositori dan Kontrol ObjectDataSource
Buat file kelas baru di folder DAL , beri nama SchoolRepository.cs, dan ganti kode yang ada dengan kode berikut:
using System;
using System.Collections.Generic;
using System.Linq;
using ContosoUniversity.DAL;
namespace ContosoUniversity.DAL
{
public class SchoolRepository : IDisposable
{
private SchoolEntities context = new SchoolEntities();
public IEnumerable<Department> GetDepartments()
{
return context.Departments.Include("Person").ToList();
}
private bool disposedValue = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
context.Dispose();
}
}
this.disposedValue = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
Kode ini menyediakan satu GetDepartments
metode yang mengembalikan semua entitas dalam Departments
kumpulan entitas. Karena Anda tahu bahwa Anda akan mengakses Person
properti navigasi untuk setiap baris yang dikembalikan, Anda menentukan pemuatan bersemangat untuk properti tersebut Include
dengan menggunakan metode . Kelas ini juga mengimplementasikan IDisposable
antarmuka untuk memastikan bahwa koneksi database dirilis saat objek dibuang.
Catatan
Praktik umumnya adalah membuat kelas repositori untuk setiap jenis entitas. Dalam tutorial ini, satu kelas repositori untuk beberapa jenis entitas digunakan. Untuk informasi selengkapnya tentang pola repositori, lihat postingan di blog tim Kerangka Kerja Entitas dan blog Julie Lerman.
Metode mengembalikan GetDepartments
IEnumerable
objek daripada IQueryable
objek untuk memastikan bahwa koleksi yang dikembalikan dapat digunakan bahkan setelah objek repositori itu sendiri dibuang. Objek IQueryable
dapat menyebabkan akses database setiap kali diakses, tetapi objek repositori mungkin dibuang pada saat kontrol terikat data mencoba merender data. Anda dapat mengembalikan jenis koleksi lain, seperti IList
objek alih-alih IEnumerable
objek. Namun, mengembalikan IEnumerable
objek memastikan bahwa Anda dapat melakukan tugas pemrosesan daftar baca-saja yang khas seperti foreach
perulangan dan kueri LINQ, tetapi Anda tidak dapat menambahkan atau menghapus item dalam koleksi, yang mungkin menyiratkan bahwa perubahan tersebut akan dipertahankan ke database.
Buat halaman Departments.aspx yang menggunakan halaman site.master , dan tambahkan markup berikut dalam Content
kontrol bernama Content2
:
<h2>Departments</h2>
<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server"
TypeName="ContosoUniversity.DAL.SchoolRepository"
DataObjectTypeName="ContosoUniversity.DAL.Department"
SelectMethod="GetDepartments" >
</asp:ObjectDataSource>
<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="DepartmentsObjectDataSource" >
<Columns>
<asp:CommandField ShowEditButton="True" ShowDeleteButton="True"
ItemStyle-VerticalAlign="Top">
</asp:CommandField>
<asp:DynamicField DataField="Name" HeaderText="Name" SortExpression="Name" ItemStyle-VerticalAlign="Top" />
<asp:DynamicField DataField="Budget" HeaderText="Budget" SortExpression="Budget" ItemStyle-VerticalAlign="Top" />
<asp:DynamicField DataField="StartDate" HeaderText="Start Date" ItemStyle-VerticalAlign="Top" />
<asp:TemplateField HeaderText="Administrator" SortExpression="Person.LastName" ItemStyle-VerticalAlign="Top" >
<ItemTemplate>
<asp:Label ID="AdministratorLastNameLabel" runat="server" Text='<%# Eval("Person.LastName") %>'></asp:Label>,
<asp:Label ID="AdministratorFirstNameLabel" runat="server" Text='<%# Eval("Person.FirstMidName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Markup ini membuat ObjectDataSource
kontrol yang menggunakan kelas repositori yang GridView
baru saja Anda buat, dan kontrol untuk menampilkan data. Kontrol GridView
menentukan perintah Edit dan Hapus , tetapi Anda belum menambahkan kode untuk mendukungnya.
Beberapa kolom menggunakan DynamicField
kontrol sehingga Anda dapat memanfaatkan fungsionalitas pemformatan dan validasi data otomatis. Agar ini berfungsi, Anda harus memanggil EnableDynamicData
metode di penanganan Page_Init
aktivitas. (DynamicControl
kontrol tidak digunakan di Administrator
bidang karena tidak berfungsi dengan properti navigasi.)
Atribut Vertical-Align="Top"
akan menjadi penting nanti ketika Anda menambahkan kolom yang memiliki kontrol berlapis GridView
ke kisi.
Buka file Departments.aspx.cs dan tambahkan pernyataan berikut using
:
using ContosoUniversity.DAL;
Kemudian tambahkan handler berikut untuk peristiwa halaman Init
:
protected void Page_Init(object sender, EventArgs e)
{
DepartmentsGridView.EnableDynamicData(typeof(Department));
}
Di folder DAL , buat file kelas baru bernama Department.cs dan ganti kode yang ada dengan kode berikut:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace ContosoUniversity.DAL
{
[MetadataType(typeof(DepartmentMetaData))]
public partial class Department
{
}
public class DepartmentMetaData
{
[DataType(DataType.Currency)]
[Range(0, 1000000, ErrorMessage = "Budget must be less than $1,000,000.00")]
public Decimal Budget { get; set; }
[DisplayFormat(DataFormatString="{0:d}",ApplyFormatInEditMode=true)]
public DateTime StartDate { get; set; }
}
}
Kode ini menambahkan metadata ke model data. Ini menentukan bahwa Budget
properti Department
entitas benar-benar mewakili mata uang meskipun jenis datanya adalah Decimal
, dan menentukan bahwa nilai harus antara 0 dan $1.000.000,00. Ini juga menentukan bahwa StartDate
properti harus diformat sebagai tanggal dalam format mm/dd/yyyy.
Jalankan halaman Departments.aspx .
Perhatikan bahwa meskipun Anda tidak menentukan string format di markup halaman Departments.aspx untuk kolom Anggaran atau Tanggal Mulai , mata uang default dan pemformatan tanggal telah diterapkan oleh DynamicField
kontrol, menggunakan metadata yang Anda berikan dalam file Department.cs .
Menambahkan Fungsionalitas Sisipkan dan Hapus
Buka SchoolRepository.cs, tambahkan kode berikut untuk membuat Insert
metode dan Delete
metode . Kode ini juga menyertakan metode bernama GenerateDepartmentID
yang menghitung nilai kunci rekaman berikutnya yang tersedia untuk digunakan oleh Insert
metode . Ini diperlukan karena database tidak dikonfigurasi untuk menghitung ini secara otomatis untuk Department
tabel.
public void InsertDepartment(Department department)
{
try
{
department.DepartmentID = GenerateDepartmentID();
context.Departments.AddObject(department);
context.SaveChanges();
}
catch (Exception ex)
{
//Include catch blocks for specific exceptions first,
//and handle or log the error as appropriate in each.
//Include a generic catch block like this one last.
throw ex;
}
}
public void DeleteDepartment(Department department)
{
try
{
context.Departments.Attach(department);
context.Departments.DeleteObject(department);
context.SaveChanges();
}
catch (Exception ex)
{
//Include catch blocks for specific exceptions first,
//and handle or log the error as appropriate in each.
//Include a generic catch block like this one last.
throw ex;
}
}
private Int32 GenerateDepartmentID()
{
Int32 maxDepartmentID = 0;
var department = (from d in GetDepartments()
orderby d.DepartmentID descending
select d).FirstOrDefault();
if (department != null)
{
maxDepartmentID = department.DepartmentID + 1;
}
return maxDepartmentID;
}
Metode Lampirkan
Metode ini DeleteDepartment
memanggil Attach
metode untuk membuat ulang tautan yang dipertahankan dalam manajer status objek konteks objek antara entitas dalam memori dan baris database yang diwakilinya. Ini harus terjadi sebelum metode memanggil SaveChanges
metode .
Konteks objek istilah mengacu pada kelas Kerangka Kerja Entitas yang berasal dari ObjectContext
kelas yang Anda gunakan untuk mengakses kumpulan entitas dan entitas Anda. Dalam kode untuk proyek ini, kelas diberi nama SchoolEntities
, dan instansnya selalu diberi nama context
.
Manajer status objek konteks objek adalah kelas yang berasal dari ObjectStateManager
kelas . Kontak objek menggunakan manajer status objek untuk menyimpan objek entitas dan untuk melacak apakah masing-masing objek sinkron dengan baris tabel atau baris yang sesuai dalam database.
Saat Anda membaca entitas, konteks objek menyimpannya di manajer status objek dan melacak apakah representasi objek tersebut sinkron dengan database. Misalnya, jika Anda mengubah nilai properti, bendera diatur untuk menunjukkan bahwa properti yang Anda ubah tidak lagi sinkron dengan database. Kemudian ketika Anda memanggil SaveChanges
metode , konteks objek tahu apa yang harus dilakukan dalam database karena manajer status objek tahu persis apa yang berbeda antara status entitas saat ini dan status database.
Namun, proses ini biasanya tidak berfungsi di aplikasi web, karena instans konteks objek yang membaca entitas, bersama dengan semua yang ada di pengelola status objeknya, dibuang setelah halaman dirender. Instans konteks objek yang harus menerapkan perubahan adalah yang baru yang dibuat untuk pemrosesan postback. Dalam kasus DeleteDepartment
metode , ObjectDataSource
kontrol membuat ulang versi asli entitas untuk Anda dari nilai dalam status tampilan, tetapi entitas yang dibuat Department
ulang ini tidak ada di manajer status objek. Jika Anda memanggil DeleteObject
metode pada entitas yang dibuat ulang ini, panggilan akan gagal karena konteks objek tidak tahu apakah entitas sinkron dengan database. Namun, memanggil metode menetapkan Attach
kembali pelacakan yang sama antara entitas yang dibuat ulang dan nilai dalam database yang awalnya dilakukan secara otomatis ketika entitas dibaca dalam instans sebelumnya dari konteks objek.
Ada kalanya Anda tidak ingin konteks objek melacak entitas di pengelola status objek, dan Anda dapat mengatur bendera untuk mencegahnya melakukan itu. Contoh ini ditampilkan dalam tutorial selanjutnya dalam seri ini.
Metode SaveChanges
Kelas repositori sederhana ini menggambarkan prinsip-prinsip dasar tentang cara melakukan operasi CRUD. Dalam contoh ini, metode dipanggil SaveChanges
segera setelah setiap pembaruan. Dalam aplikasi produksi, Anda mungkin ingin memanggil SaveChanges
metode dari metode terpisah untuk memberi Anda lebih banyak kontrol saat database diperbarui. (Di akhir tutorial berikutnya Anda akan menemukan tautan ke laporan resmi yang membahas unit pola kerja yang merupakan salah satu pendekatan untuk mengoordinasikan pembaruan terkait.) Perhatikan juga bahwa dalam contoh, DeleteDepartment
metode tidak menyertakan kode untuk menangani konflik konkurensi; kode untuk melakukannya akan ditambahkan dalam tutorial selanjutnya dalam seri ini.
Mengambil Nama Instruktur untuk Dipilih Saat Menyisipkan
Pengguna harus dapat memilih administrator dari daftar instruktur dalam daftar drop-down saat membuat departemen baru. Oleh karena itu, tambahkan kode berikut ke SchoolRepository.cs untuk membuat metode untuk mengambil daftar instruktur menggunakan tampilan yang Anda buat sebelumnya:
public IEnumerable<InstructorName> GetInstructorNames()
{
return context.InstructorNames.OrderBy("it.FullName").ToList();
}
Membuat Halaman untuk Menyisipkan Departemen
Buat halaman DepartmentsAdd.aspx yang menggunakan halaman Site.Master , dan tambahkan markup berikut dalam Content
kontrol bernama Content2
:
<h2>Departments</h2>
<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server"
TypeName="ContosoUniversity.DAL.SchoolRepository" DataObjectTypeName="ContosoUniversity.DAL.Department"
InsertMethod="InsertDepartment" >
</asp:ObjectDataSource>
<asp:DetailsView ID="DepartmentsDetailsView" runat="server"
DataSourceID="DepartmentsObjectDataSource" AutoGenerateRows="False"
DefaultMode="Insert" OnItemInserting="DepartmentsDetailsView_ItemInserting">
<Fields>
<asp:DynamicField DataField="Name" HeaderText="Name" />
<asp:DynamicField DataField="Budget" HeaderText="Budget" />
<asp:DynamicField DataField="StartDate" HeaderText="Start Date" />
<asp:TemplateField HeaderText="Administrator">
<InsertItemTemplate>
<asp:ObjectDataSource ID="InstructorsObjectDataSource" runat="server"
TypeName="ContosoUniversity.DAL.SchoolRepository"
DataObjectTypeName="ContosoUniversity.DAL.InstructorName"
SelectMethod="GetInstructorNames" >
</asp:ObjectDataSource>
<asp:DropDownList ID="InstructorsDropDownList" runat="server"
DataSourceID="InstructorsObjectDataSource"
DataTextField="FullName" DataValueField="PersonID" OnInit="DepartmentsDropDownList_Init">
</asp:DropDownList>
</InsertItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
<asp:ValidationSummary ID="DepartmentsValidationSummary" runat="server"
ShowSummary="true" DisplayMode="BulletList" />
Markup ini membuat dua ObjectDataSource
kontrol, satu untuk menyisipkan entitas baru Department
dan satu untuk mengambil nama instruktur untuk DropDownList
kontrol yang digunakan untuk memilih administrator departemen. Markup membuat DetailsView
kontrol untuk memasukkan departemen baru, dan menentukan handler untuk peristiwa kontrol ItemInserting
sehingga Anda dapat mengatur Administrator
nilai kunci asing. Di akhir adalah ValidationSummary
kontrol untuk menampilkan pesan kesalahan.
Buka DepartmentsAdd.aspx.cs dan tambahkan pernyataan berikut using
:
using ContosoUniversity.DAL;
Tambahkan variabel dan metode kelas berikut:
private DropDownList administratorsDropDownList;
protected void Page_Init(object sender, EventArgs e)
{
DepartmentsDetailsView.EnableDynamicData(typeof(Department));
}
protected void DepartmentsDropDownList_Init(object sender, EventArgs e)
{
administratorsDropDownList = sender as DropDownList;
}
protected void DepartmentsDetailsView_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
e.Values["Administrator"] = administratorsDropDownList.SelectedValue;
}
Metode ini Page_Init
memungkinkan fungsionalitas Data Dinamis. Handler untuk DropDownList
peristiwa kontrol Init
menyimpan referensi ke kontrol, dan handler untuk DetailsView
peristiwa kontrol Inserting
menggunakan referensi tersebut PersonID
untuk mendapatkan nilai instruktur yang dipilih dan memperbarui Administrator
properti kunci asing entitas Department
.
Jalankan halaman, tambahkan informasi untuk departemen baru, lalu klik tautan Sisipkan .
Masukkan nilai untuk departemen baru lainnya. Masukkan angka yang lebih besar dari 1.000.000,00 di bidang Anggaran dan tab ke bidang berikutnya. Tanda bintang muncul di bidang , dan jika Anda menahan penunjuk mouse di atasnya, Anda dapat melihat pesan kesalahan yang Anda masukkan di metadata untuk bidang tersebut.
Klik Sisipkan, dan Anda melihat pesan kesalahan yang ditampilkan oleh ValidationSummary
kontrol di bagian bawah halaman.
Selanjutnya, tutup browser dan buka halaman Departments.aspx . Tambahkan kemampuan hapus ke halaman Departments.aspx dengan menambahkan DeleteMethod
atribut ke ObjectDataSource
kontrol, dan DataKeyNames
atribut ke GridView
kontrol. Tag pembuka untuk kontrol ini sekarang akan menyerupai contoh berikut:
<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server"
TypeName="ContosoUniversity.DAL.SchoolRepository"
DataObjectTypeName="ContosoUniversity.DAL.Department"
SelectMethod="GetDepartments"
DeleteMethod="DeleteDepartment" >
<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID" >
Jalankan halaman.
Hapus departemen yang Anda tambahkan saat menjalankan halaman DepartmentsAdd.aspx .
Menambahkan Fungsionalitas Pembaruan
Buka SchoolRepository.cs dan tambahkan metode berikut Update
:
public void UpdateDepartment(Department department, Department origDepartment)
{
try
{
context.Departments.Attach(origDepartment);
context.ApplyCurrentValues("Departments", department);
context.SaveChanges();
}
catch (Exception ex)
{
//Include catch blocks for specific exceptions first,
//and handle or log the error as appropriate in each.
//Include a generic catch block like this one last.
throw ex;
}
}
Saat Anda mengklik Perbarui di halaman Departments.aspx , ObjectDataSource
kontrol membuat dua Department
entitas untuk diteruskan ke UpdateDepartment
metode . Satu berisi nilai asli yang telah disimpan dalam status tampilan, dan yang lainnya berisi nilai baru yang dimasukkan dalam GridView
kontrol. Kode dalam UpdateDepartment
metode meneruskan Department
entitas yang memiliki nilai asli ke Attach
metode untuk membuat pelacakan antara entitas dan apa yang ada di database. Kemudian kode meneruskan Department
entitas yang memiliki nilai baru ke ApplyCurrentValues
metode . Konteks objek membandingkan nilai lama dan baru. Jika nilai baru berbeda dari nilai lama, konteks objek mengubah nilai properti. Metode ini SaveChanges
kemudian hanya memperbarui kolom yang diubah dalam database. (Namun, jika fungsi pembaruan untuk entitas ini dipetakan ke prosedur tersimpan, seluruh baris akan diperbarui terlepas dari kolom mana yang diubah.)
Buka file Departments.aspx dan tambahkan atribut berikut ke DepartmentsObjectDataSource
kontrol:
UpdateMethod="UpdateDepartment"
ConflictDetection="CompareAllValues"
Ini menyebabkan nilai lama disimpan dalam status tampilan sehingga dapat dibandingkan dengan nilai baru dalamUpdate
metode .OldValuesParameterFormatString="orig{0}"
Ini menginformasikan kontrol bahwa nama parameter nilai asli adalahorigDepartment
.
Markup untuk tag ObjectDataSource
pembuka kontrol sekarang menyerupai contoh berikut:
<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server"
TypeName="ContosoUniversity.DAL.SchoolRepository"
DataObjectTypeName="ContosoUniversity.DAL.Department"
SelectMethod="GetDepartments" DeleteMethod="DeleteDepartment"
UpdateMethod="UpdateDepartment"
ConflictDetection="CompareAllValues"
OldValuesParameterFormatString="orig{0}" >
OnRowUpdating="DepartmentsGridView_RowUpdating"
Tambahkan atribut ke GridView
kontrol. Anda akan menggunakan ini untuk mengatur Administrator
nilai properti berdasarkan baris yang dipilih pengguna dalam daftar drop-down. Tag GridView
pembuka sekarang menyerupai contoh berikut:
<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID"
OnRowUpdating="DepartmentsGridView_RowUpdating">
EditItemTemplate
Tambahkan kontrol untuk Administrator
kolom ke GridView
kontrol, segera setelah kontrol untuk kolom tersebutItemTemplate
:
<EditItemTemplate>
<asp:ObjectDataSource ID="InstructorsObjectDataSource" runat="server" DataObjectTypeName="ContosoUniversity.DAL.InstructorName"
SelectMethod="GetInstructorNames" TypeName="ContosoUniversity.DAL.SchoolRepository">
</asp:ObjectDataSource>
<asp:DropDownList ID="InstructorsDropDownList" runat="server" DataSourceID="InstructorsObjectDataSource"
SelectedValue='<%# Eval("Administrator") %>'
DataTextField="FullName" DataValueField="PersonID" OnInit="DepartmentsDropDownList_Init" >
</asp:DropDownList>
</EditItemTemplate>
Kontrol ini EditItemTemplate
mirip InsertItemTemplate
dengan kontrol di halaman DepartmentsAdd.aspx . Perbedaannya adalah bahwa nilai awal kontrol diatur menggunakan SelectedValue
atribut .
GridView
Sebelum kontrol, tambahkan kontrol seperti yang ValidationSummary
Anda lakukan di halaman DepartmentsAdd.aspx.
<asp:ValidationSummary ID="DepartmentsValidationSummary" runat="server"
ShowSummary="true" DisplayMode="BulletList" />
Buka Departments.aspx.cs dan segera setelah deklarasi kelas parsial, tambahkan kode berikut untuk membuat bidang privat untuk mereferensikan DropDownList
kontrol:
private DropDownList administratorsDropDownList;
Kemudian tambahkan handler untuk DropDownList
peristiwa kontrol Init
dan GridView
peristiwa kontrol RowUpdating
:
protected void DepartmentsDropDownList_Init(object sender, EventArgs e)
{
administratorsDropDownList = sender as DropDownList;
}
protected void DepartmentsGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
e.NewValues["Administrator"] = administratorsDropDownList.SelectedValue;
}
Handler untuk Init
peristiwa menyimpan referensi ke DropDownList
kontrol di bidang kelas. Handler untuk RowUpdating
peristiwa menggunakan referensi untuk mendapatkan nilai yang dimasukkan pengguna dan menerapkannya ke Administrator
properti Department
entitas.
Gunakan halaman DepartmentsAdd.aspx untuk menambahkan departemen baru, lalu jalankan halaman Departments.aspx dan klik Edit pada baris yang Anda tambahkan.
Catatan
Anda tidak akan bisa mengedit baris yang tidak Anda tambahkan (yaitu, yang sudah ada dalam database), karena data yang tidak valid dalam database; administrator untuk baris yang dibuat dengan database adalah siswa. Jika Anda mencoba mengedit salah satunya, Anda akan mendapatkan halaman kesalahan yang melaporkan kesalahan seperti 'InstructorsDropDownList' has a SelectedValue which is invalid because it does not exist in the list of items.
Jika Anda memasukkan jumlah Anggaran yang tidak valid lalu klik Perbarui, Anda akan melihat tanda bintang dan pesan kesalahan yang sama dengan yang Anda lihat di halaman Departments.aspx .
Ubah nilai bidang atau pilih administrator lain dan klik Perbarui. Perubahan ditampilkan.
Ini menyelesaikan pengenalan menggunakan ObjectDataSource
kontrol untuk operasi CRUD dasar (buat, baca, perbarui, hapus) dengan Kerangka Kerja Entitas. Anda telah membangun aplikasi n-tingkat sederhana, tetapi lapisan logika bisnis masih digabungkan erat ke lapisan akses data, yang mempersulit pengujian unit otomatis. Dalam tutorial berikut, Anda akan melihat cara menerapkan pola repositori untuk memfasilitasi pengujian unit.