Freigeben über


Erste Schritte mit Entity Framework 4.0 Database First und ASP.NET 4 Web Forms – Teil 5

von Tom Dykstra

Die Contoso University-Beispielwebanwendung veranschaulicht, wie sie ASP.NET Web Forms Anwendungen mit Entity Framework 4.0 und Visual Studio 2010 erstellen. Informationen zur Tutorialreihe finden Sie im ersten Tutorial der Reihe.

Im vorherigen Tutorial haben Sie mit der Verwendung des EntityDataSource -Steuerelements begonnen, um mit verwandten Daten zu arbeiten. Sie haben mehrere Hierarchieebenen und bearbeitete Daten in Navigationseigenschaften angezeigt. In diesem Tutorial arbeiten Sie weiterhin mit verwandten Daten, indem Sie Beziehungen hinzufügen und löschen und eine neue Entität hinzufügen, die eine Beziehung zu einer vorhandenen Entität aufweist.

Sie erstellen eine Seite, auf der Kurse hinzugefügt werden, die Abteilungen zugewiesen sind. Die Abteilungen sind bereits vorhanden, und wenn Sie einen neuen Kurs erstellen, stellen Sie gleichzeitig eine Beziehung zwischen dem Kurs und einer vorhandenen Abteilung her.

Screenshot des Fensters

Sie erstellen auch eine Seite, die mit einer m:n-Beziehung funktioniert, indem Sie einem Kurs einen Kursleiter zuweisen (eine Beziehung zwischen zwei Entitäten hinzufügen, die Sie auswählen) oder einen Kursleiter aus einem Kurs entfernen (wobei eine Beziehung zwischen zwei von Ihnen ausgewählten Entitäten entfernt wird). In der Datenbank führt das Hinzufügen einer Beziehung zwischen einem Kursleiter und einem Kurs dazu, dass der CourseInstructor Zuordnungstabelle eine neue Zeile hinzugefügt wird. Zum Entfernen einer Beziehung wird eine Zeile aus der CourseInstructor Zuordnungstabelle gelöscht. Dies geschieht jedoch im Entity Framework, indem Sie Navigationseigenschaften festlegen, ohne explizit auf die CourseInstructor Tabelle zu verweisen.

Screenshot des Fensters

Hinzufügen einer Entität mit einer Beziehung zu einer vorhandenen Entität

Erstellen Sie eine neue Webseite namens CoursesAdd.aspx, die die Seite Site.Master master verwendet, und fügen Sie dem Steuerelement mit dem Content Namen Content2das folgende Markup hinzu:

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

Dieses Markup erstellt ein EntityDataSource Steuerelement, das Kurse auswählt, das das Einfügen ermöglicht und einen Handler für das Inserting Ereignis angibt. Sie verwenden den Handler, um die Department Navigationseigenschaft zu aktualisieren, wenn eine neue Course Entität erstellt wird.

Das Markup erstellt auch ein DetailsView Steuerelement, das zum Hinzufügen neuer Course Entitäten verwendet werden soll. Das Markup verwendet gebundene Felder für Course Entitätseigenschaften. Sie müssen den CourseID Wert eingeben, da es sich nicht um ein vom System generiertes ID-Feld handelt. Stattdessen handelt es sich um eine Kursnummer, die beim Erstellen des Kurses manuell angegeben werden muss.

Sie verwenden ein Vorlagenfeld für die Department Navigationseigenschaft, da Navigationseigenschaften nicht mit BoundField Steuerelementen verwendet werden können. Das Vorlagenfeld enthält eine Dropdownliste zum Auswählen der Abteilung. Die Dropdownliste wird an den Departments Entitätssatz gebunden, indem anstelle Bindvon Eval verwendet wird, da Navigationseigenschaften nicht direkt gebunden werden können, um sie zu aktualisieren. Sie geben einen Handler für das DropDownList -Ereignis des Steuerelements Init an, damit Sie einen Verweis auf das Steuerelement speichern können, der durch den Code verwendet wird, der den DepartmentID Fremdschlüssel aktualisiert.

Fügen Sie in CoursesAdd.aspx.cs direkt nach der partiellen Klassendeklaration ein Klassenfeld hinzu, um einen Verweis auf das DepartmentsDropDownList Steuerelement zu enthalten:

private DropDownList departmentDropDownList;

Fügen Sie einen Handler für das DepartmentsDropDownList -Ereignis des Steuerelements Init hinzu, damit Sie einen Verweis auf das Steuerelement speichern können. Dadurch können Sie den Wert abrufen, den der Benutzer eingegeben hat, und ihn verwenden, um den DepartmentID Wert der Course Entität zu aktualisieren.

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

Fügen Sie einen Handler für das DetailsView -Ereignis des Steuerelements Inserting hinzu:

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

Wenn der Benutzer auf klickt Insert, wird das Inserting Ereignis ausgelöst, bevor der neue Datensatz eingefügt wird. Der Code im Handler ruft den DepartmentID vom -Steuerelement ab DropDownList und verwendet es, um den Wert festzulegen, der für die DepartmentID -Eigenschaft der Course Entität verwendet wird.

Das Entity Framework kümmert sich um das Hinzufügen dieses Kurses zur Courses Navigationseigenschaft der zugeordneten Department Entität. Außerdem wird die Abteilung der Department Navigationseigenschaft der Course Entität hinzugefügt.

Führen Sie die Seite aus.

Screenshot des Fensters

Geben Sie eine ID, einen Titel, eine Anzahl von Gutschriften ein, und wählen Sie eine Abteilung aus, und klicken Sie dann auf Einfügen.

Führen Sie die Seite Courses.aspx aus, und wählen Sie dieselbe Abteilung aus, um den neuen Kurs anzuzeigen.

Bild03

Arbeiten mit m:n-Beziehungen

Die Beziehung zwischen dem Entitätssatz Courses und dem Entitätssatz People ist eine m:n-Beziehung. Eine Course Entität verfügt über eine Navigationseigenschaft namens People , die null, eine oder mehrere verwandte Person Entitäten enthalten kann (die für den Kurs zugewiesenen Dozenten darstellen). Und eine Person Entität verfügt über eine Navigationseigenschaft namens Courses , die null, eine oder mehrere verwandte Course Entitäten enthalten kann (die Kurse darstellen, denen der Dozent zugewiesen ist). Ein Dozent kann mehrere Kurse unterrichten, und ein Kurs kann von mehreren Kursleitern unterrichtet werden. In diesem Abschnitt der exemplarischen Vorgehensweise fügen Sie Beziehungen zwischen Person - und -Entitäten hinzu und Course entfernen diese, indem Sie die Navigationseigenschaften der zugehörigen Entitäten aktualisieren.

Erstellen Sie eine neue Webseite namens InstructorsCourses.aspx, die die Seite Site.Master master verwendet, und fügen Sie dem Steuerelement mit dem Content Namen Content2das folgende Markup hinzu:

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

Dieses Markup erstellt ein EntityDataSource Steuerelement, das den Namen und PersonID die Person Entitäten für Kursleiter abruft. Ein DropDrownList Steuerelement ist an das EntityDataSource -Steuerelement gebunden. Das DropDownList -Steuerelement gibt einen Handler für das DataBound -Ereignis an. Sie verwenden diesen Handler, um die beiden Dropdownlisten, die Kurse anzeigen, mit Daten zu binden.

Das Markup erstellt auch die folgende Gruppe von Steuerelementen, die zum Zuweisen eines Kurses zum ausgewählten Kursleiter verwendet werden sollen:

  • Ein DropDownList Steuerelement zum Auswählen eines zuzuweisenden Kurses. Dieses Steuerelement wird mit Kursen aufgefüllt, die dem ausgewählten Kursleiter derzeit nicht zugewiesen sind.
  • Ein Button Steuerelement zum Initiieren der Zuweisung.
  • Ein Label Steuerelement, das eine Fehlermeldung anzeigt, wenn die Zuweisung fehlschlägt.

Schließlich erstellt das Markup auch eine Gruppe von Steuerelementen, die zum Entfernen eines Kurses aus dem ausgewählten Kursleiter verwendet werden sollen.

Fügen Sie in InstructorsCourses.aspx.cs eine using-Anweisung hinzu:

using ContosoUniversity.DAL;

Fügen Sie eine Methode zum Auffüllen der beiden Dropdownlisten hinzu, die Kurse anzeigen:

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

Dieser Code ruft alle Kurse aus dem Courses Entitätssatz ab und ruft die Kurse aus der Courses Navigationseigenschaft der Person Entität für den ausgewählten Kursleiter ab. Anschließend wird bestimmt, welche Kurse diesem Kursleiter zugewiesen sind, und die Dropdownlisten werden entsprechend aufgefüllt.

Fügen Sie einen Handler für das Ereignis der AssignClick Schaltfläche hinzu:

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

Dieser Code ruft die Person Entität für den ausgewählten Kursleiter ab, ruft die Course Entität für den ausgewählten Kurs ab und fügt den ausgewählten Kurs der Courses Navigationseigenschaft der Entität des Kursleiters Person hinzu. Anschließend werden die Änderungen in der Datenbank gespeichert und die Dropdownlisten neu aufgefüllt, damit die Ergebnisse sofort angezeigt werden.

Fügen Sie einen Handler für das Ereignis der RemoveClick Schaltfläche hinzu:

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

Dieser Code ruft die Person Entität für den ausgewählten Kursleiter ab, ruft die Course Entität für den ausgewählten Kurs ab und entfernt den ausgewählten Kurs aus der Navigationseigenschaft Courses der Person Entität. Anschließend werden die Änderungen in der Datenbank gespeichert und die Dropdownlisten neu aufgefüllt, damit die Ergebnisse sofort angezeigt werden.

Fügen Sie der Page_Load -Methode Code hinzu, der sicherstellt, dass die Fehlermeldungen nicht angezeigt werden, wenn kein Fehler gemeldet werden muss, und fügen Sie Handler für die DataBound Ereignisse und SelectedIndexChanged der Dropdownliste der Dozenten hinzu, um die Dropdownlisten der Kurse aufzufüllen:

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

Führen Sie die Seite aus.

Screenshot des Fensters

Wählen Sie einen Kursleiter aus. In der Dropdownliste Kurs zuweisen werden die Kurse angezeigt, die der Kursleiter nicht unterrichtet, und in der Dropdownliste Kurs entfernen werden die Kurse angezeigt, denen der Kursleiter bereits zugewiesen ist. Wählen Sie im Abschnitt Kurs zuweisen einen Kurs aus, und klicken Sie dann auf Zuweisen. Der Kurs wird in die Dropdownliste "Kurs entfernen " verschoben. Wählen Sie im Abschnitt Kurs entfernen einen Kurs aus, und klicken Sie auf Entfernen. Der Kurs wechselt in die Dropdownliste Kurs zuweisen .

Sie haben nun einige weitere Möglichkeiten zum Arbeiten mit verwandten Daten kennengelernt. Im folgenden Tutorial erfahren Sie, wie Sie die Vererbung im Datenmodell verwenden, um die Verwaltbarkeit Ihrer Anwendung zu verbessern.