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
Aplikasi web sampel Contoso University menunjukkan cara membuat aplikasi ASP.NET Web Forms menggunakan Entity Framework 4.0 dan Visual Studio 2010. Untuk informasi tentang seri tutorial, lihat tutorial pertama dalam seri
Bekerja dengan Data Terkait
Dalam tutorial sebelumnya, Anda menggunakan EntityDataSource
kontrol untuk memfilter, mengurutkan, dan mengelompokkan data. Dalam tutorial ini Anda akan menampilkan dan memperbarui data terkait.
Anda akan membuat halaman Instruktur yang menampilkan daftar instruktur. Saat Anda memilih instruktur, Anda akan melihat daftar kursus yang diajarkan oleh instruktur tersebut. Saat Anda memilih kursus, Anda akan melihat detail untuk kursus dan daftar siswa yang terdaftar dalam kursus. Anda dapat mengedit nama instruktur, tanggal sewa, dan penugasan kantor. Penetapan kantor adalah kumpulan entitas terpisah yang Anda akses melalui properti navigasi.
Anda dapat menautkan data master untuk merinci data dalam markup atau dalam kode. Di bagian tutorial ini, Anda akan menggunakan kedua metode.
Menampilkan dan Memperbarui Entitas Terkait dalam Kontrol GridView
Buat halaman web baru bernama Instructors.aspx yang menggunakan halaman master Site.Master , dan tambahkan markup berikut ke Content
kontrol bernama Content2
:
<h2>Instructors</h2>
<div>
<asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="People"
Where="it.HireDate is not null" Include="OfficeAssignment" EnableUpdate="True">
</asp:EntityDataSource>
</div>
Markup ini membuat EntityDataSource
kontrol yang memilih instruktur dan mengaktifkan pembaruan. Elemen div
mengonfigurasi markup untuk dirender di sebelah kiri sehingga Anda dapat menambahkan kolom di sebelah kanan nanti.
EntityDataSource
Antara markup dan tag penutup</div>
, tambahkan markup berikut yang membuat GridView
kontrol dan Label
kontrol yang akan Anda gunakan untuk pesan kesalahan:
<asp:GridView ID="InstructorsGridView" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" DataKeyNames="PersonID" DataSourceID="InstructorsEntityDataSource"
OnSelectedIndexChanged="InstructorsGridView_SelectedIndexChanged"
SelectedRowStyle-BackColor="LightGray"
onrowupdating="InstructorsGridView_RowUpdating">
<Columns>
<asp:CommandField ShowSelectButton="True" ShowEditButton="True" />
<asp:TemplateField HeaderText="Name" SortExpression="LastName">
<ItemTemplate>
<asp:Label ID="InstructorLastNameLabel" runat="server" Text='<%# Eval("LastName") %>'></asp:Label>,
<asp:Label ID="InstructorFirstNameLabel" runat="server" Text='<%# Eval("FirstMidName") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="InstructorLastNameTextBox" runat="server" Text='<%# Bind("FirstMidName") %>' Width="7em"></asp:TextBox>
<asp:TextBox ID="InstructorFirstNameTextBox" runat="server" Text='<%# Bind("LastName") %>' Width="7em"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Hire Date" SortExpression="HireDate">
<ItemTemplate>
<asp:Label ID="InstructorHireDateLabel" runat="server" Text='<%# Eval("HireDate", "{0:d}") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="InstructorHireDateTextBox" runat="server" Text='<%# Bind("HireDate", "{0:d}") %>' Width="7em"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Office Assignment" SortExpression="OfficeAssignment.Location">
<ItemTemplate>
<asp:Label ID="InstructorOfficeLabel" runat="server" Text='<%# Eval("OfficeAssignment.Location") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="InstructorOfficeTextBox" runat="server"
Text='<%# Eval("OfficeAssignment.Location") %>' Width="7em"
oninit="InstructorOfficeTextBox_Init"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
<SelectedRowStyle BackColor="LightGray"></SelectedRowStyle>
</asp:GridView>
<asp:Label ID="ErrorMessageLabel" runat="server" Text="" Visible="false" ViewStateMode="Disabled"></asp:Label>
Kontrol ini GridView
memungkinkan pemilihan baris, menyoroti baris yang dipilih dengan warna latar belakang abu-abu muda, dan menentukan penangan (yang akan Anda buat nanti) untuk SelectedIndexChanged
peristiwa dan Updating
. Ini juga menentukan PersonID
untuk DataKeyNames
properti , sehingga nilai kunci baris yang dipilih dapat diteruskan ke kontrol lain yang akan Anda tambahkan nanti.
Kolom terakhir berisi penetapan kantor instruktur, yang disimpan dalam properti Person
navigasi entitas karena berasal dari entitas terkait. Perhatikan bahwa EditItemTemplate
elemen menentukan alih-alih Eval
Bind
, karena GridView
kontrol tidak dapat langsung mengikat properti navigasi untuk memperbaruinya. Anda akan memperbarui penetapan kantor dalam kode. Untuk melakukannya, Anda memerlukan referensi ke TextBox
kontrol, dan Anda akan mendapatkan dan menyimpannya dalam TextBox
peristiwa kontrol Init
.
GridView
Mengikuti kontrol adalah Label
kontrol yang digunakan untuk pesan kesalahan. Properti kontrol Visible
adalah false
, dan status tampilan dimatikan, sehingga label hanya akan muncul ketika kode membuatnya terlihat sebagai respons terhadap kesalahan.
Buka file Instructors.aspx.cs dan tambahkan pernyataan berikut using
:
using ContosoUniversity.DAL;
Tambahkan bidang kelas privat segera setelah deklarasi nama kelas parsial untuk menyimpan referensi ke kotak teks penetapan kantor.
private TextBox instructorOfficeTextBox;
Tambahkan stub untuk SelectedIndexChanged
penanganan aktivitas yang akan Anda tambahkan kodenya nanti. Tambahkan juga handler untuk peristiwa kontrol Init
penugasan TextBox
kantor sehingga Anda dapat menyimpan referensi ke TextBox
kontrol. Anda akan menggunakan referensi ini untuk mendapatkan nilai yang dimasukkan pengguna untuk memperbarui entitas yang terkait dengan properti navigasi.
protected void InstructorsGridView_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void InstructorOfficeTextBox_Init(object sender, EventArgs e)
{
instructorOfficeTextBox = sender as TextBox;
}
Anda akan menggunakan GridView
peristiwa kontrol Updating
untuk memperbarui Location
properti entitas terkait OfficeAssignment
. Tambahkan handler berikut untuk Updating
peristiwa:
protected void InstructorsGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
using (var context = new SchoolEntities())
{
var instructorBeingUpdated = Convert.ToInt32(e.Keys[0]);
var officeAssignment = (from o in context.OfficeAssignments
where o.InstructorID == instructorBeingUpdated
select o).FirstOrDefault();
try
{
if (String.IsNullOrWhiteSpace(instructorOfficeTextBox.Text) == false)
{
if (officeAssignment == null)
{
context.OfficeAssignments.AddObject(OfficeAssignment.CreateOfficeAssignment(instructorBeingUpdated, instructorOfficeTextBox.Text, null));
}
else
{
officeAssignment.Location = instructorOfficeTextBox.Text;
}
}
else
{
if (officeAssignment != null)
{
context.DeleteObject(officeAssignment);
}
}
context.SaveChanges();
}
catch (Exception)
{
e.Cancel = true;
ErrorMessageLabel.Visible = true;
ErrorMessageLabel.Text = "Update failed.";
//Add code to log the error.
}
}
}
Kode ini dijalankan saat pengguna mengklik Perbarui secara berturut-turut GridView
. Kode menggunakan LINQ ke Entitas untuk mengambil OfficeAssignment
entitas yang terkait dengan entitas saat ini Person
, menggunakan PersonID
baris yang dipilih dari argumen peristiwa.
Kode kemudian mengambil salah satu tindakan berikut tergantung pada nilai dalam InstructorOfficeTextBox
kontrol:
- Jika kotak teks memiliki nilai dan tidak
OfficeAssignment
ada entitas untuk diperbarui, kotak teks akan membuatnya. - Jika kotak teks memiliki nilai dan ada
OfficeAssignment
entitas, kotak teks akanLocation
memperbarui nilai properti. - Jika kotak teks kosong dan
OfficeAssignment
entitas ada, kotak teks akan menghapus entitas.
Setelah ini, ia menyimpan perubahan ke database. Jika terjadi pengecualian, pengecualian akan menampilkan pesan kesalahan.
Jalankan halaman.
Klik Edit dan semua bidang berubah menjadi kotak teks.
Ubah salah satu nilai ini, termasuk Penugasan Office. Klik Perbarui dan Anda akan melihat perubahan yang tercermin dalam daftar.
Menampilkan Entitas Terkait dalam Kontrol Terpisah
Setiap instruktur dapat mengajarkan satu atau beberapa kursus, sehingga Anda akan menambahkan EntityDataSource
kontrol dan GridView
kontrol untuk mencantumkan kursus yang terkait dengan instruktur mana pun yang dipilih dalam kontrol instruktur GridView
. Untuk membuat judul dan EntityDataSource
kontrol untuk entitas kursus, tambahkan markup berikut antara kontrol pesan Label
kesalahan dan tag penutup </div>
:
<h3>Courses Taught</h3>
<asp:EntityDataSource ID="CoursesEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="Courses"
Where="@PersonID IN (SELECT VALUE instructor.PersonID FROM it.People AS instructor)">
<WhereParameters>
<asp:ControlParameter ControlID="InstructorsGridView" Type="Int32" Name="PersonID" PropertyName="SelectedValue" />
</WhereParameters>
</asp:EntityDataSource>
Parameter Where
berisi nilai PersonID
instruktur yang barisnya dipilih dalam InstructorsGridView
kontrol. Properti Where
berisi perintah subpilih yang mendapatkan semua entitas terkait Person
dari Course
properti navigasi entitas People
dan memilih Course
entitas hanya jika salah satu entitas terkait Person
berisi nilai yang dipilih PersonID
.
Untuk membuat GridView
kontrol., tambahkan markup berikut segera setelah CoursesEntityDataSource
kontrol (sebelum tag penutup </div>
):
<asp:GridView ID="CoursesGridView" runat="server"
DataSourceID="CoursesEntityDataSource"
AllowSorting="True" AutoGenerateColumns="False"
SelectedRowStyle-BackColor="LightGray"
DataKeyNames="CourseID">
<EmptyDataTemplate>
<p>No courses found.</p>
</EmptyDataTemplate>
<Columns>
<asp:CommandField ShowSelectButton="True" />
<asp:BoundField DataField="CourseID" HeaderText="ID" ReadOnly="True" SortExpression="CourseID" />
<asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
<asp:TemplateField HeaderText="Department" SortExpression="DepartmentID">
<ItemTemplate>
<asp:Label ID="GridViewDepartmentLabel" runat="server" Text='<%# Eval("Department.Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Karena tidak ada kursus yang akan ditampilkan jika tidak ada instruktur yang dipilih, EmptyDataTemplate
elemen disertakan.
Jalankan halaman.
Pilih instruktur yang memiliki satu atau beberapa kursus yang ditetapkan, dan kursus atau kursus muncul dalam daftar. (Catatan: meskipun skema database memungkinkan beberapa kursus, dalam data pengujian yang disediakan dengan database tidak ada instruktur yang benar-benar memiliki lebih dari satu kursus. Anda dapat menambahkan kursus ke database sendiri menggunakan jendela Server Explorer atau halaman CoursesAdd.aspx , yang akan Anda tambahkan di tutorial selanjutnya.)
Kontrol CoursesGridView
hanya memperlihatkan beberapa bidang kursus. Untuk menampilkan semua detail kursus, Anda akan menggunakan DetailsView
kontrol untuk kursus yang dipilih pengguna. Di Instructors.aspx, tambahkan markup berikut setelah tag penutup </div>
(pastikan Anda menempatkan markup ini setelah tag div penutup, bukan sebelumnya):
<div>
<h3>Course Details</h3>
<asp:EntityDataSource ID="CourseDetailsEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="Courses"
AutoGenerateWhereClause="False" Where="it.CourseID = @CourseID" Include="Department,OnlineCourse,OnsiteCourse,StudentGrades.Person"
OnSelected="CourseDetailsEntityDataSource_Selected">
<WhereParameters>
<asp:ControlParameter ControlID="CoursesGridView" Type="Int32" Name="CourseID" PropertyName="SelectedValue" />
</WhereParameters>
</asp:EntityDataSource>
<asp:DetailsView ID="CourseDetailsView" runat="server" AutoGenerateRows="False"
DataSourceID="CourseDetailsEntityDataSource">
<EmptyDataTemplate>
<p>
No course selected.</p>
</EmptyDataTemplate>
<Fields>
<asp:BoundField DataField="CourseID" HeaderText="ID" ReadOnly="True" SortExpression="CourseID" />
<asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
<asp:BoundField DataField="Credits" HeaderText="Credits" SortExpression="Credits" />
<asp:TemplateField HeaderText="Department">
<ItemTemplate>
<asp:Label ID="DetailsViewDepartmentLabel" runat="server" Text='<%# Eval("Department.Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Location">
<ItemTemplate>
<asp:Label ID="LocationLabel" runat="server" Text='<%# Eval("OnsiteCourse.Location") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="URL">
<ItemTemplate>
<asp:Label ID="URLLabel" runat="server" Text='<%# Eval("OnlineCourse.URL") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>
</div>
Markup ini membuat EntityDataSource
kontrol yang terikat ke Courses
set entitas. Properti Where
memilih kursus menggunakan CourseID
nilai baris yang dipilih dalam kontrol kursus GridView
. Markup menentukan handler untuk Selected
acara, yang akan Anda gunakan nanti untuk menampilkan nilai siswa, yang merupakan tingkat lain yang lebih rendah dalam hierarki.
Di Instructors.aspx.cs, buat stub berikut untuk metode .CourseDetailsEntityDataSource_Selected
(Anda akan mengisi stub ini nanti dalam tutorial; untuk saat ini, Anda membutuhkannya sehingga halaman akan mengkompilasi dan menjalankan.)
protected void CourseDetailsEntityDataSource_Selected(object sender, EntityDataSourceSelectedEventArgs e)
{
}
Jalankan halaman.
Awalnya tidak ada detail kursus karena tidak ada kursus yang dipilih. Pilih instruktur yang memiliki kursus yang ditetapkan, lalu pilih kursus untuk melihat detailnya.
Menggunakan Peristiwa EntityDataSource "Dipilih" untuk Menampilkan Data Terkait
Terakhir, Anda ingin menunjukkan kepada semua siswa terdaftar dan nilai mereka untuk kursus yang dipilih. Untuk melakukan ini, Anda akan menggunakan Selected
peristiwa kontrol yang EntityDataSource
terikat ke kursus DetailsView
.
Di Instruktur.aspx, tambahkan markup berikut setelah DetailsView
kontrol:
<h3>Student Grades</h3>
<asp:ListView ID="GradesListView" runat="server">
<EmptyDataTemplate>
<p>No student grades found.</p>
</EmptyDataTemplate>
<LayoutTemplate>
<table border="1" runat="server" id="itemPlaceholderContainer">
<tr runat="server">
<th runat="server">
Name
</th>
<th runat="server">
Grade
</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="StudentLastNameLabel" runat="server" Text='<%# Eval("Person.LastName") %>' />,
<asp:Label ID="StudentFirstNameLabel" runat="server" Text='<%# Eval("Person.FirstMidName") %>' />
</td>
<td>
<asp:Label ID="StudentGradeLabel" runat="server" Text='<%# Eval("Grade") %>' />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
Markup ini membuat ListView
kontrol yang menampilkan daftar siswa dan nilai mereka untuk kursus yang dipilih. Tidak ada sumber data yang ditentukan karena Anda akan menggabungkan data kontrol dalam kode. Elemen EmptyDataTemplate
menyediakan pesan untuk ditampilkan ketika tidak ada kursus yang dipilih—dalam hal ini, tidak ada siswa yang ditampilkan. Elemen LayoutTemplate
membuat tabel HTML untuk menampilkan daftar, dan ItemTemplate
menentukan kolom yang akan ditampilkan. ID siswa dan nilai siswa berasal dari StudentGrade
entitas, dan nama siswa berasal dari Person
entitas yang disediakan Kerangka Kerja Entitas di Person
properti StudentGrade
navigasi entitas.
Di Instruktur.aspx.cs, ganti metode stubbed-out CourseDetailsEntityDataSource_Selected
dengan kode berikut:
protected void CourseDetailsEntityDataSource_Selected(object sender, EntityDataSourceSelectedEventArgs e)
{
var course = e.Results.Cast<Course>().FirstOrDefault();
if (course != null)
{
var studentGrades = course.StudentGrades.ToList();
GradesListView.DataSource = studentGrades;
GradesListView.DataBind();
}
}
Argumen peristiwa untuk peristiwa ini menyediakan data yang dipilih dalam bentuk koleksi, yang akan memiliki nol item jika tidak ada yang dipilih atau satu item jika Course
entitas dipilih.
Course
Jika entitas dipilih, kode menggunakan First
metode untuk mengonversi koleksi menjadi satu objek. Kemudian mendapatkan StudentGrade
entitas dari properti navigasi, mengonversinya menjadi koleksi, dan mengikat GradesListView
kontrol ke koleksi.
Ini cukup untuk menampilkan nilai, tetapi Anda ingin memastikan bahwa pesan dalam templat data kosong ditampilkan pertama kali halaman ditampilkan dan setiap kali kursus tidak dipilih. Untuk melakukannya, buat metode berikut, yang akan Anda panggil dari dua tempat:
private void ClearStudentGradesDataSource()
{
var emptyStudentGradesList = new List<StudentGrade>();
GradesListView.DataSource = emptyStudentGradesList;
GradesListView.DataBind();
}
Panggil metode baru ini dari Page_Load
metode untuk menampilkan templat data kosong saat pertama kali halaman ditampilkan. Dan panggil dari InstructorsGridView_SelectedIndexChanged
metode karena peristiwa itu dinaikkan ketika instruktur dipilih, yang berarti kursus baru dimuat ke dalam kontrol kursus GridView
dan belum ada yang dipilih. Berikut adalah dua panggilan:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ClearStudentGradesDataSource();
}
}
protected void InstructorsGridView_SelectedIndexChanged(object sender, EventArgs e)
{
ClearStudentGradesDataSource();
}
Jalankan halaman.
Pilih instruktur yang memiliki kursus yang ditetapkan, lalu pilih kursus.
Anda sekarang telah melihat beberapa cara untuk bekerja dengan data terkait. Dalam tutorial berikut, Anda akan mempelajari cara menambahkan hubungan antara entitas yang ada, cara menghapus hubungan, dan cara menambahkan entitas baru yang memiliki hubungan dengan entitas yang ada.