Bagikan melalui


Memulai Entity Framework 4.0 Database First dan ASP.NET 4 Web Forms - Bagian 5

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

Dalam tutorial sebelumnya Anda mulai menggunakan EntityDataSource kontrol untuk bekerja dengan data terkait. Anda menampilkan beberapa tingkat hierarki dan data yang diedit di properti navigasi. Dalam tutorial ini Anda akan terus bekerja dengan data terkait dengan menambahkan dan menghapus hubungan dan dengan menambahkan entitas baru yang memiliki hubungan dengan entitas yang ada.

Anda akan membuat halaman yang menambahkan kursus yang ditetapkan ke departemen. Departemen sudah ada, dan ketika Anda membuat kursus baru, pada saat yang sama Anda akan menjalin hubungan antara itu dan departemen yang ada.

Cuplikan layar jendela Internet Explorer, yang memperlihatkan bidang teks Tambahkan Kursus dengan bidang teks ID, Judul, dan Kredit dan dropdown Departemen.

Anda juga akan membuat halaman yang berfungsi dengan hubungan banyak ke banyak dengan menetapkan instruktur ke kursus (menambahkan hubungan antara dua entitas yang Anda pilih) atau menghapus instruktur dari kursus (menghapus hubungan antara dua entitas yang Anda pilih). Dalam database, menambahkan hubungan antara instruktur dan kursus menghasilkan baris baru yang ditambahkan ke CourseInstructor tabel asosiasi; menghapus hubungan melibatkan penghapusan baris dari CourseInstructor tabel asosiasi. Namun, Anda melakukan ini di Kerangka Kerja Entitas dengan mengatur properti navigasi, tanpa mengacu pada CourseInstructor tabel secara eksplisit.

Cuplikan layar jendela Internet Explorer, yang menampilkan tampilan Tetapkan Instruktur ke Kursus atau Hapus dari Kursus.

Menambahkan Entitas dengan Hubungan ke Entitas yang Ada

Buat halaman web baru bernama CoursesAdd.aspx yang menggunakan halaman master Site.Master , dan tambahkan markup berikut ke Content kontrol bernama Content2:

<h2>Add Courses</h2>
    <asp:EntityDataSource ID="CoursesEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
        EntitySetName="Courses" 
        EnableInsert="True" EnableDelete="True" >
    </asp:EntityDataSource>
    <asp:DetailsView ID="CoursesDetailsView" runat="server" AutoGenerateRows="False"
        DataSourceID="CoursesEntityDataSource" DataKeyNames="CourseID"
        DefaultMode="Insert" oniteminserting="CoursesDetailsView_ItemInserting">
        <Fields>
            <asp:BoundField DataField="CourseID" HeaderText="ID" />
            <asp:BoundField DataField="Title" HeaderText="Title" />
            <asp:BoundField DataField="Credits" HeaderText="Credits" />
            <asp:TemplateField HeaderText="Department">
                <InsertItemTemplate>
                    <asp:EntityDataSource ID="DepartmentsEntityDataSource" runat="server" ConnectionString="name=SchoolEntities"
                        DefaultContainerName="SchoolEntities" EnableDelete="True" EnableFlattening="False"
                        EntitySetName="Departments" EntityTypeFilter="Department">
                    </asp:EntityDataSource>
                    <asp:DropDownList ID="DepartmentsDropDownList" runat="server" DataSourceID="DepartmentsEntityDataSource"
                        DataTextField="Name" DataValueField="DepartmentID"
                        oninit="DepartmentsDropDownList_Init">
                    </asp:DropDownList>
                </InsertItemTemplate>
            </asp:TemplateField>
            <asp:CommandField ShowInsertButton="True" />
        </Fields>
    </asp:DetailsView>

Markup ini membuat EntityDataSource kontrol yang memilih kursus, yang memungkinkan penyisipan, dan yang menentukan handler untuk peristiwa tersebut Inserting . Anda akan menggunakan handler untuk memperbarui Department properti navigasi saat entitas baru Course dibuat.

Markup juga membuat kontrol yang DetailsView akan digunakan untuk menambahkan entitas baru Course . Markup menggunakan bidang terikat untuk Course properti entitas. Anda harus memasukkan CourseID nilai karena ini bukan bidang ID yang dihasilkan sistem. Sebaliknya, ini adalah nomor kursus yang harus ditentukan secara manual ketika kursus dibuat.

Anda menggunakan bidang templat untuk Department properti navigasi karena properti navigasi tidak dapat digunakan dengan BoundField kontrol. Bidang templat menyediakan daftar drop-down untuk memilih departemen. Daftar drop-down terikat ke entitas yang Departments ditetapkan dengan menggunakan Eval daripada Bind, sekali lagi karena Anda tidak dapat langsung mengikat properti navigasi untuk memperbaruinya. Anda menentukan handler untuk DropDownList peristiwa kontrol Init sehingga Anda dapat menyimpan referensi ke kontrol untuk digunakan oleh kode yang memperbarui DepartmentID kunci asing.

Di CoursesAdd.aspx.cs tepat setelah deklarasi kelas parsial, tambahkan bidang kelas untuk menyimpan referensi ke DepartmentsDropDownList kontrol:

private DropDownList departmentDropDownList;

Tambahkan handler untuk DepartmentsDropDownList peristiwa kontrol Init sehingga Anda dapat menyimpan referensi ke kontrol. Ini memungkinkan Anda mendapatkan nilai yang telah dimasukkan pengguna dan menggunakannya untuk memperbarui DepartmentID nilai Course entitas.

protected void DepartmentsDropDownList_Init(object sender, EventArgs e)
{
    departmentDropDownList = sender as DropDownList;
}

Tambahkan handler untuk DetailsView peristiwa kontrol Inserting :

protected void CoursesDetailsView_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
    var departmentID = Convert.ToInt32(departmentDropDownList.SelectedValue);
    e.Values["DepartmentID"] = departmentID;
}

Saat pengguna mengklik Insert, Inserting peristiwa dinaikkan sebelum rekaman baru disisipkan. Kode dalam handler mendapatkan DepartmentID dari DropDownList kontrol dan menggunakannya untuk mengatur nilai yang akan digunakan untuk DepartmentID properti Course entitas.

Kerangka Kerja Entitas akan mengurus penambahan kursus ini ke Courses properti navigasi entitas terkait Department . Ini juga menambahkan departemen ke Department properti Course navigasi entitas.

Jalankan halaman.

Cuplikan layar jendela Internet Explorer, yang memperlihatkan tampilan Tambahkan Kursus dengan bidang teks ID, Judul, dan Kredit dan dropdown Departemen.

Masukkan ID, judul, sejumlah kredit, dan pilih departemen, lalu klik Sisipkan.

Jalankan halaman Courses.aspx , dan pilih departemen yang sama untuk melihat kursus baru.

Gambar03

Bekerja dengan Hubungan Banyak-ke-Banyak

Hubungan antara Courses set entitas dan People set entitas adalah hubungan banyak-ke-banyak. Entitas Course memiliki properti navigasi bernama People yang dapat berisi nol, satu, atau beberapa entitas terkait Person (mewakili instruktur yang ditetapkan untuk mengajar kursus tersebut). Person Dan entitas memiliki properti navigasi bernama Courses yang dapat berisi nol, satu, atau lebih entitas terkait Course (mewakili kursus yang ditetapkan untuk diajarkan instruktur). Satu instruktur mungkin mengajar beberapa kursus, dan satu kursus mungkin diajarkan oleh beberapa instruktur. Di bagian panduan ini, Anda akan menambahkan dan menghapus hubungan antara Person entitas dan Course dengan memperbarui properti navigasi entitas terkait.

Buat halaman web baru bernama InstructorsCourses.aspx yang menggunakan halaman master Site.Master , dan tambahkan markup berikut ke Content kontrol bernama Content2:

<h2>Assign Instructors to Courses or Remove from Courses</h2>
    <br />
    <asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
        EntitySetName="People"
        Where="it.HireDate is not null" Select="it.LastName + ', ' + it.FirstMidName AS Name, it.PersonID">
    </asp:EntityDataSource>
    Select an Instructor:
    <asp:DropDownList ID="InstructorsDropDownList" runat="server" DataSourceID="InstructorsEntityDataSource"
        AutoPostBack="true" DataTextField="Name" DataValueField="PersonID"
        OnSelectedIndexChanged="InstructorsDropDownList_SelectedIndexChanged" 
        OnDataBound="InstructorsDropDownList_DataBound">
    </asp:DropDownList>
    <h3>
        Assign a Course</h3>
    <br />
    Select a Course:
    <asp:DropDownList ID="UnassignedCoursesDropDownList" runat="server"
        DataTextField="Title" DataValueField="CourseID">
    </asp:DropDownList>
    <br />
    <asp:Button ID="AssignCourseButton" runat="server" Text="Assign" OnClick="AssignCourseButton_Click" />
    <br />
    <asp:Label ID="CourseAssignedLabel" runat="server" Visible="false" Text="Assignment successful"></asp:Label>
    <br />
    <h3>
        Remove a Course</h3>
    <br />
    Select a Course:
    <asp:DropDownList ID="AssignedCoursesDropDownList" runat="server"
        DataTextField="title" DataValueField="courseiD">
    </asp:DropDownList>
    <br />
    <asp:Button ID="RemoveCourseButton" runat="server" Text="Remove" OnClick="RemoveCourseButton_Click" />
    <br />
    <asp:Label ID="CourseRemovedLabel" runat="server" Visible="false" Text="Removal successful"></asp:Label>

Markup ini membuat EntityDataSource kontrol yang mengambil nama dan PersonIDPerson entitas untuk instruktur. DropDrownList Kontrol terikat pada EntityDataSource kontrol. Kontrol DropDownList menentukan handler untuk peristiwa tersebut DataBound . Anda akan menggunakan handler ini untuk menggabungkan data dua daftar drop-down yang menampilkan kursus.

Markup juga membuat grup kontrol berikut yang akan digunakan untuk menetapkan kursus ke instruktur yang dipilih:

  • DropDownList Kontrol untuk memilih kursus yang akan ditetapkan. Kontrol ini akan diisi dengan kursus yang saat ini tidak ditetapkan ke instruktur yang dipilih.
  • Button Kontrol untuk memulai penugasan.
  • Label Kontrol untuk menampilkan pesan kesalahan jika penugasan gagal.

Akhirnya, markup juga membuat sekelompok kontrol yang akan digunakan untuk menghapus kursus dari instruktur yang dipilih.

Di InstructorsCourses.aspx.cs, tambahkan pernyataan penggunaan:

using ContosoUniversity.DAL;

Tambahkan metode untuk mengisi dua daftar drop-down yang menampilkan kursus:

private void PopulateDropDownLists()
{
    using (var context = new SchoolEntities())
    {
        var allCourses = (from c in context.Courses
                          select c).ToList();

        var instructorID = Convert.ToInt32(InstructorsDropDownList.SelectedValue);
        var instructor = (from p in context.People.Include("Courses")
                          where p.PersonID == instructorID
                          select p).First();

        var assignedCourses = instructor.Courses.ToList();
        var unassignedCourses = allCourses.Except(assignedCourses.AsEnumerable()).ToList();

        UnassignedCoursesDropDownList.DataSource = unassignedCourses;
        UnassignedCoursesDropDownList.DataBind();
        UnassignedCoursesDropDownList.Visible = true;

        AssignedCoursesDropDownList.DataSource = assignedCourses;
        AssignedCoursesDropDownList.DataBind();
        AssignedCoursesDropDownList.Visible = true;
    }
}

Kode ini mendapatkan semua kursus dari Courses set entitas dan mendapatkan kursus dari Courses properti Person navigasi entitas untuk instruktur yang dipilih. Kemudian menentukan kursus mana yang ditetapkan untuk instruktur tersebut dan mengisi daftar drop-down yang sesuai.

Tambahkan handler untuk peristiwa tombol AssignClick :

protected void AssignCourseButton_Click(object sender, EventArgs e)
{
    using (var context = new SchoolEntities())
    {
        var instructorID = Convert.ToInt32(InstructorsDropDownList.SelectedValue);
        var instructor = (from p in context.People
                          where p.PersonID == instructorID
                          select p).First();
        var courseID = Convert.ToInt32(UnassignedCoursesDropDownList.SelectedValue);
        var course = (from c in context.Courses
                      where c.CourseID == courseID
                      select c).First();
        instructor.Courses.Add(course);
        try
        {
            context.SaveChanges();
            PopulateDropDownLists();
            CourseAssignedLabel.Text = "Assignment successful.";
        }
        catch (Exception)
        {
            CourseAssignedLabel.Text = "Assignment unsuccessful.";
            //Add code to log the error.
        }
        CourseAssignedLabel.Visible = true;
    }
}

Kode ini mendapatkan Person entitas untuk instruktur yang dipilih, mendapatkan Course entitas untuk kursus yang dipilih, dan menambahkan kursus yang dipilih ke Courses properti navigasi entitas instruktur Person . Kemudian menyimpan perubahan ke database dan mengisi kembali daftar drop-down sehingga hasilnya dapat segera dilihat.

Tambahkan handler untuk peristiwa tombol RemoveClick :

protected void RemoveCourseButton_Click(object sender, EventArgs e)
{
    using (var context = new SchoolEntities())
    {
        var instructorID = Convert.ToInt32(InstructorsDropDownList.SelectedValue);
        var instructor = (from p in context.People
                          where p.PersonID == instructorID
                          select p).First();
        var courseID = Convert.ToInt32(AssignedCoursesDropDownList.SelectedValue);
        var courses = instructor.Courses;
        var courseToRemove = new Course();
        foreach (Course c in courses)
        {
            if (c.CourseID == courseID)
            {
                courseToRemove = c;
                break;
            }
        }
        try
        {
            courses.Remove(courseToRemove);
            context.SaveChanges();
            PopulateDropDownLists();
            CourseRemovedLabel.Text = "Removal successful.";
        }
        catch (Exception)
        {
            CourseRemovedLabel.Text = "Removal unsuccessful.";
            //Add code to log the error.
        }
        CourseRemovedLabel.Visible = true;
    }
}

Kode ini mendapatkan Person entitas untuk instruktur yang dipilih, mendapatkan Course entitas untuk kursus yang dipilih, dan menghapus kursus yang dipilih dari Person properti navigasi entitas Courses . Kemudian menyimpan perubahan ke database dan mengisi kembali daftar drop-down sehingga hasilnya dapat segera dilihat.

Tambahkan kode ke Page_Load metode yang memastikan pesan kesalahan tidak terlihat ketika tidak ada kesalahan untuk dilaporkan, dan tambahkan penangan untuk DataBoundSelectedIndexChanged dan peristiwa daftar drop-down instruktur untuk mengisi daftar drop-down kursus:

protected void Page_Load(object sender, EventArgs e)
{
    CourseAssignedLabel.Visible = false;
    CourseRemovedLabel.Visible = false;
}

protected void InstructorsDropDownList_DataBound(object sender, EventArgs e)
{
    PopulateDropDownLists();
}

protected void InstructorsDropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
    PopulateDropDownLists();
}

Jalankan halaman.

Cuplikan layar jendela Internet Explorer, yang memperlihatkan tetapkan Instruktur ke Kursus atau Hapus dari tampilan Kursus dengan dropdown yang sesuai.

Pilih instruktur. Daftar drop-down Tetapkan Kursus menampilkan kursus yang tidak diajarkan instruktur, dan daftar drop-down Hapus Kursus menampilkan kursus yang sudah ditetapkan instruktur. Di bagian Tetapkan Kursus , pilih kursus lalu klik Tetapkan. Kursus berpindah ke daftar drop-down Hapus Kursus . Pilih kursus di bagian Hapus Kursus dan klik Hapus. Kursus berpindah ke daftar drop-down Tetapkan Kursus .

Anda sekarang telah melihat beberapa cara lagi untuk bekerja dengan data terkait. Dalam tutorial berikut, Anda akan mempelajari cara menggunakan pewarisan dalam model data untuk meningkatkan keberlanjutan aplikasi Anda.