Freigeben über


Erste Schritte mit Entity Framework 4.0-Datenbank und ASP.NET 4 Webformularen – Teil 5

Von Tom Dykstra

Die Contoso University-Beispielwebanwendung veranschaulicht, wie ASP.NET Web Forms-Anwendungen mithilfe von Entity Framework 4.0 und Visual Studio 2010 erstellt werden. Informationen zur Lernprogrammreihe finden Sie im ersten Lernprogramm in der Reihe

Im vorherigen Lernprogramm 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 Lernprogramm 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 hat.

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 Internet Explorer-Fensters, in dem die Ansicht

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

Screenshot des Internet Explorer-Fensters, das die Ansicht

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

Erstellen Sie eine neue Webseite mit dem Namen CoursesAdd.aspx , die die Gestaltungsvorlage "Site.Master " verwendet, und fügen Sie dem Content Steuerelement das folgende Markup hinzu 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>

Dieses Markup erstellt ein EntityDataSource Steuerelement, das Kurse auswählt, die das Einfügen ermöglichen 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 außerdem 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 hierbei nicht um ein vom System generiertes ID-Feld handelt. Stattdessen ist es 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 stellt eine Dropdownliste bereit, um die Abteilung auszuwählen. Die Dropdownliste ist an das Departments-Entitätsset mithilfe von Eval anstelle von Bind gebunden, da Navigationseigenschaften nicht direkt gebunden werden können, um sie zu aktualisieren. Sie geben einen Handler für das Ereignis des DropDownList Steuerelements Init an, sodass Sie einen Verweis auf das Steuerelement zur Verwendung durch den Code speichern können, 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 Ereignis des DepartmentsDropDownList Steuerelements Init hinzu, damit Sie einen Verweis auf das Steuerelement speichern können. Auf diese Weise 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 Ereignis des DetailsView Steuerelements Inserting hinzu:

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

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

Das Entity Framework sorgt dafür, diesen Kurs zur Courses Navigations-Eigenschaft der zugehörigen Department Entität hinzuzufügen. Außerdem wird die Abteilung zur Department Navigationseigenschaft der Course Entität hinzugefügt.

Laden Sie die Seite.

Screenshot des Internet Explorer-Fensters, in dem die Ansicht

Geben Sie eine ID, einen Titel, eine Reihe 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 Viele-zu-Viele-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 mit dem Namen People, die Null, eine oder mehrere verwandte Person Entitäten enthalten kann (die Dozenten darstellen, die diesem Kurs zugewiesen sind). Und eine Person Entität verfügt über eine Navigationseigenschaft mit dem Namen Courses, die Null, eine oder mehrere verwandte Course Entitäten enthalten kann (die Kurse darstellen, die von dem Kursleiter unterrichtet werden sollen). Ein Kursleiter kann mehrere Kurse unterrichten, und ein Kurs kann von mehreren Kursleitern unterrichtet werden. In diesem Abschnitt der Anleitung fügen Sie Beziehungen zwischen Person und Course Entitäten hinzu und entfernen sie, indem Sie die Navigationseigenschaften der zugehörigen Entitäten aktualisieren.

Erstellen Sie eine neue Webseite mit dem Namen InstructorsCourses.aspx , die die Gestaltungsvorlage "Site.Master " verwendet, und fügen Sie dem Content Steuerelement das folgende Markup hinzu 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>

Dieses Markup erstellt ein EntityDataSource Steuerelement, das den Namen und PersonID der Person Entitäten für Lehrkräfte 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 zu databindieren, die Kurse anzeigen.

Das Markup erstellt außerdem 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 ausgefüllt, die dem ausgewählten Kursleiter derzeit nicht zugewiesen sind.
  • Ein Button Steuerelement zum Initiieren der Zuweisung.
  • Ein Label Steuerelement zum Anzeigen einer Fehlermeldung, wenn die Zuordnung 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 füllt die Dropdownlisten entsprechend auf.

Fügen Sie einen Handler für das Ereignis der Assign Schaltfläche Click 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 in die Navigationseigenschaft `Courses` der `Person` Entität des Kursleiters ein. Anschließend werden die Änderungen in der Datenbank gespeichert und die Dropdownlisten erneut aufgefüllt, sodass die Ergebnisse sofort angezeigt werden können.

Fügen Sie einen Handler für das Ereignis der Remove Schaltfläche Click 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 erneut aufgefüllt, sodass die Ergebnisse sofort angezeigt werden können.

Fügen Sie der Page_Load Methode Code hinzu, der sicherstellt, dass die Fehlermeldungen nicht sichtbar sind, wenn kein Fehler gemeldet werden kann, und fügen Sie Handler für die DataBound Dropdownliste der Kursleiter und SelectedIndexChanged Ereignisse hinzu, um die Dropdownlisten für 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();
}

Laden Sie die Seite.

Screenshot des Internet Explorer-Fensters, in dem die Ansicht

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 wechselt zur Dropdownliste " Kurs entfernen ". Wählen Sie einen Kurs im Abschnitt " Kurs entfernen" aus, und klicken Sie auf "Entfernen". Der Kurs wechselt zur Dropdownliste " Kurs zuweisen ".

Sie haben nun einige weitere Möglichkeiten zum Arbeiten mit verwandten Daten gesehen. Im folgenden Lernprogramm erfahren Sie, wie Sie die Vererbung im Datenmodell verwenden, um die Aufrechterhaltung ihrer Anwendung zu verbessern.