Aracılığıyla paylaş


Entity Framework 4.0 Database First ve ASP.NET 4 Web Forms ile Çalışmaya Başlama - Bölüm 4

tarafından Tom Dykstra

Contoso University örnek web uygulaması, Entity Framework 4.0 ve Visual Studio 2010 kullanarak ASP.NET Web Forms uygulamaları oluşturmayı gösterir. Öğretici serisi hakkında bilgi için serideki ilk öğreticiye bakın

Önceki öğreticide EntityDataSource , verileri filtrelemek, sıralamak ve gruplandırmak için denetimi kullandınız. Bu öğreticide ilgili verileri görüntüleyecek ve güncelleştireceksiniz.

Eğitmen listesini gösteren Eğitmenler sayfasını oluşturacaksınız. Bir eğitmen seçtiğinizde, bu eğitmen tarafından öğretilen derslerin listesini görürsünüz. Bir kursu seçtiğinizde, kursun ayrıntılarını ve kursa kayıtlı öğrencilerin listesini görürsünüz. Eğitmenin adını, işe alma tarihini ve ofis ödevini düzenleyebilirsiniz. Ofis ataması, gezinti özelliği aracılığıyla erişdiğiniz ayrı bir varlık kümesidir.

Ana verileri işaretlemedeki veya koddaki ayrıntılı verilere bağlayabilirsiniz. Öğreticinin bu bölümünde her iki yöntemi de kullanacaksınız.

Resim01

Site.Master ana sayfasını kullanan Instructors.aspx adlı yeni bir web sayfası oluşturun ve adlı Content2denetime aşağıdaki işaretlemeyi Content ekleyin:

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

Bu işaretleme, eğitmenleri seçen ve güncelleştirmeleri etkinleştiren bir EntityDataSource denetim oluşturur. div öğesi, daha sonra sağ tarafa sütun ekleyebilmeniz için işaretlemeyi solda işleyecek şekilde yapılandırıyor.

İşaretlemeyi EntityDataSource ve kapanış </div> etiketinin arasına bir denetim ve hata iletileri için kullanacağınız bir Label denetim oluşturan GridView aşağıdaki işaretlemeyi ekleyin:

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

Bu GridView denetim satır seçimini etkinleştirir, seçili satırı açık gri arka plan rengiyle vurgular ve ve Updating olayları için SelectedIndexChanged işleyicileri (daha sonra oluşturacaksınız) belirtir. Ayrıca özelliği için DataKeyNames de belirtirPersonID, böylece seçilen satırın anahtar değeri daha sonra ekleyeceğiniz başka bir denetime geçirilebilir.

Son sütun, ilişkili bir varlıktan geldiği için varlığın gezinti özelliğinde depolanan eğitmenin ofis atamasını Person içerir. EditItemTemplate Denetim, bunları güncelleştirmek için gezinti özelliklerine doğrudan bağlanamadığından öğesinin BindGridView yerine belirttiğine Eval dikkat edin. Kodda ofis atamasını güncelleştireceksiniz. Bunu yapmak için denetime TextBox bir başvuru gerekir ve bunu alıp denetimin Init olayına TextBox kaydedersiniz.

Denetimin takipi GridView , hata iletileri için kullanılan bir Label denetimdir. Denetimin Visible özelliği olur falseve görünüm durumu kapalıdır, böylece etiket yalnızca kod bir hataya yanıt olarak görünür hale geldiğinde görünür.

Instructors.aspx.cs dosyasını açın ve aşağıdaki using deyimi ekleyin:

using ContosoUniversity.DAL;

Ofis ataması metin kutusuna başvuruyu tutmak için kısmi sınıf adı bildiriminden hemen sonra bir özel sınıf alanı ekleyin.

private TextBox instructorOfficeTextBox;

Daha sonra kod ekleyeceğiniz olay işleyicisi için bir saptama SelectedIndexChanged ekleyin. Ayrıca, denetime bir başvuru depolayabileceğiniz office atama TextBox denetiminin Init olayı için TextBox bir işleyici ekleyin. Gezinti özelliğiyle ilişkili varlığı güncelleştirmek için kullanıcının girdiği değeri almak için bu başvuruyu kullanacaksınız.

protected void InstructorsGridView_SelectedIndexChanged(object sender, EventArgs e)
{
}

protected void InstructorOfficeTextBox_Init(object sender, EventArgs e)
{
    instructorOfficeTextBox = sender as TextBox;
}

İlişkili varlığın GridView özelliğini güncelleştirmek Location için denetimin Updating olayını kullanacaksınız.OfficeAssignment Olay için aşağıdaki işleyiciyi Updating ekleyin:

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

Bu kod, kullanıcı bir GridView satırda Güncelleştir'e tıkladığında çalıştırılır. Kod, olay bağımsız değişkeninden seçilen satırı kullanarak geçerli Person varlıkla ilişkili varlığı PersonID almak OfficeAssignment için LINQ to Entities kullanır.

Kod daha sonra denetimdeki değere bağlı olarak aşağıdaki eylemlerden InstructorOfficeTextBox birini gerçekleştirir:

  • Metin kutusunda bir değer varsa ve güncelleştirilecek varlık yoksa OfficeAssignment , bir değer oluşturur.
  • Metin kutusu bir değere sahipse ve varlık OfficeAssignment varsa özellik değerini güncelleştirir Location .
  • Metin kutusu boşsa ve bir OfficeAssignment varlık varsa varlığı siler.

Bundan sonra, değişiklikleri veritabanına kaydeder. Bir özel durum oluşursa, bir hata iletisi görüntüler.

Sayfayı çalıştırın.

Görüntü02

Düzenle'ye tıklayın ve tüm alanlar metin kutularına dönüşür.

Görüntü03

Office Ataması da dahil olmak üzere bu değerlerden herhangi birini değiştirin. Güncelleştir'e tıkladığınızda değişikliklerin listeye yansıtılmış olduğunu görürsünüz.

Her eğitmen bir veya daha fazla kurs öğretebilir. Bu nedenle, eğitmen denetiminde GridView hangi eğitmen seçilirse o eğitmenle ilişkili kursları listelemek için bir EntityDataSourceGridView denetim ve denetim eklersiniz. Kurs varlıkları için başlık ve EntityDataSource denetim oluşturmak için hata iletisi Label denetimi ile kapanış </div> etiketi arasına aşağıdaki işaretlemeyi ekleyin:

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

parametresi, Where denetimde satırı seçilen InstructorsGridView eğitmenin değerini PersonID içerir. özelliği, Where bir varlığın People gezinti özelliğinden tüm ilişkili Person varlıkları alan ve yalnızca ilişkili Person varlıklardan biri seçili PersonID değeri içeriyorsa varlığı seçen Course bir Course alt seçim komutu içerir.

Denetimi oluşturmak için denetimin GridView hemen ardından CoursesEntityDataSource (kapanış </div> etiketinden önce) aşağıdaki işaretlemeyi ekleyin:

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

Eğitmen seçilmediği takdirde hiçbir kurs görüntülenmeyeceğinden, bir EmptyDataTemplate öğe eklenir.

Sayfayı çalıştırın.

Görüntü04

Atanmış bir veya daha fazla kursa sahip bir eğitmen seçin; kurs veya kurslar listede görünür. (Not: Veritabanı şeması birden çok kursa izin verse de, veritabanıyla birlikte sağlanan test verilerinde hiçbir eğitmenin aslında birden fazla kursu yoktur. Sunucu Gezgini penceresini veya sonraki bir öğreticide ekleyeceğiniz CoursesAdd.aspx sayfasını kullanarak veritabanına kendiniz kurs ekleyebilirsiniz.)

Görüntü05

Denetimde CoursesGridView yalnızca birkaç kurs alanı gösterilir. Bir kursun tüm ayrıntılarını görüntülemek için kullanıcının seçtiği kurs için bir DetailsView denetim kullanacaksınız. Instructors.aspx dosyasında, kapanış </div> etiketinden sonra aşağıdaki işaretlemeyi ekleyin (bu işaretlemeyi öncesinde değil, kapanış div etiketinden sonra yerleştirdiğinizden emin olun):

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

Bu işaretleme, varlık kümesine Courses bağlı bir EntityDataSource denetim oluşturur. özelliği, Where kurs denetiminde CourseID seçilen satırın değerini kullanarak bir kursu GridView seçer. İşaretleme olay için bir işleyici belirtir. Bu işleyiciyi Selected daha sonra hiyerarşide daha düşük olan başka bir düzey olan öğrenci notlarını görüntülemek için kullanacaksınız.

Instructors.aspx.cs dosyasında yöntemi için aşağıdaki saptamayı CourseDetailsEntityDataSource_Selected oluşturun. (Bu saptamayı öğreticinin ilerleyen bölümlerinde dolduracaksınız; şimdilik sayfanın derlenip çalışması için buna ihtiyacınız olacak.)

protected void CourseDetailsEntityDataSource_Selected(object sender, EntityDataSourceSelectedEventArgs e)
{
}

Sayfayı çalıştırın.

Görüntü06

Kurs seçilmemiş olduğundan başlangıçta kurs ayrıntıları yoktur. Kursun atandığı eğitmeni seçin ve ardından ayrıntıları görmek için bir kurs seçin.

Görüntü07

Son olarak, seçilen kurs için tüm kayıtlı öğrencileri ve notlarını göstermek istiyorsunuz. Bunu yapmak için, kursa SelectedDetailsViewbağlı denetimin EntityDataSource olayını kullanacaksınız.

Instructors.aspx'da, denetimden sonra aşağıdaki işaretlemeyi DetailsView ekleyin:

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

Bu işaretleme, seçilen kurs için öğrencilerin ve notlarının listesini görüntüleyen bir denetim oluşturur ListView . Denetimi kodda veri bağlamanız nedeniyle veri kaynağı belirtilmedi. EmptyDataTemplate öğesi, hiçbir ders seçilmediğinde görüntülenecek bir ileti sağlar; bu durumda görüntülenecek öğrenci yoktur. LayoutTemplate öğesi, listeyi görüntülemek için bir HTML tablosu oluşturur ve ItemTemplate görüntülenecek sütunları belirtir. Öğrenci kimliği ve öğrenci notu varlıktanStudentGrade, öğrenci adı ise Entity Framework'ün varlığın gezinti özelliğinde Person kullanıma sağladığı varlıktandır PersonStudentGrade.

Instructors.aspx.cs dosyasında stubbed-out CourseDetailsEntityDataSource_Selected yöntemini aşağıdaki kodla değiştirin:

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();
    }
}

Bu olayın olay bağımsız değişkeni, seçilen verileri bir koleksiyon biçiminde sağlar ve hiçbir şey seçilmezse sıfır öğe veya varlık seçilirse bir Course öğe olur. Bir Course varlık seçilirse kod, koleksiyonu tek bir nesneye dönüştürmek için yöntemini kullanır First . Daha sonra gezinti özelliğinden varlıkları alır StudentGrade , bunları bir koleksiyona dönüştürür ve denetimi koleksiyona bağlar GradesListView .

Bu, notları görüntülemek için yeterlidir, ancak boş veri şablonundaki iletinin, sayfa ilk kez görüntülendiğinde ve bir kurs seçili değilken görüntülendiğinden emin olmak istiyorsunuz. Bunu yapmak için, iki yerden çağıracağınız aşağıdaki yöntemi oluşturun:

private void ClearStudentGradesDataSource()
{
    var emptyStudentGradesList = new List<StudentGrade>();
    GradesListView.DataSource = emptyStudentGradesList;
    GradesListView.DataBind();
}

Sayfa ilk kez görüntülendiğinde boş veri şablonunu görüntülemek için yönteminden Page_Load bu yeni yöntemi çağırın. Bunu yönteminden InstructorsGridView_SelectedIndexChanged çağırın çünkü bu olay bir eğitmen seçildiğinde oluşturulur; bu da yeni kursların kurs GridView denetimine yüklendiği ve henüz seçilmediği anlamına gelir. İki çağrı şunlardır:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        ClearStudentGradesDataSource();                
    }
}
protected void InstructorsGridView_SelectedIndexChanged(object sender, EventArgs e)
{
    ClearStudentGradesDataSource();
}

Sayfayı çalıştırın.

Görüntü08

Kursun atandığı eğitmeni seçin ve ardından kursu seçin.

Görüntü09

Artık ilgili verilerle çalışmanın birkaç yolunu gördünüz. Aşağıdaki öğreticide, var olan varlıklar arasında ilişki eklemeyi, ilişkileri kaldırmayı ve var olan bir varlıkla ilişkisi olan yeni bir varlığı eklemeyi öğreneceksiniz.