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.
Arbeiten mit verwandten Daten, Fortsetzung
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.
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.
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 Content2
das 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 Bind
von 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.
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.
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 Content2
das 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 Assign
Click
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 Remove
Click
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.
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.