Erste Schritte mit Entity Framework 4.0 Database First und ASP.NET 4 Web Forms – Teil 3
von Tom Dykstra
Die Beispielwebanwendung der Contoso University veranschaulicht das Erstellen ASP.NET Web Forms Anwendungen mit Entity Framework 4.0 und Visual Studio 2010. Informationen zur Tutorialreihe finden Sie im ersten Tutorial der Reihe.
Filtern, Sortieren und Gruppieren von Daten
Im vorherigen Tutorial haben Sie das EntityDataSource
Steuerelement zum Anzeigen und Bearbeiten von Daten verwendet. In diesem Tutorial filtern, sortieren und gruppen Sie Daten. Wenn Sie dazu Eigenschaften des EntityDataSource
Steuerelements festlegen, unterscheidet sich die Syntax von anderen Datenquellensteuerelementen. Wie Sie sehen werden, können Sie jedoch das QueryExtender
Steuerelement verwenden, um diese Unterschiede zu minimieren.
Sie ändern die Seite Students.aspx , um nach Kursteilnehmern zu filtern, nach Name zu sortieren und nach Name zu suchen. Sie ändern auch die Seite Courses.aspx , um Kurse für die ausgewählte Abteilung anzuzeigen und nach Kursen nach Namen zu suchen. Schließlich fügen Sie der Seite About.aspx Studentenstatistiken hinzu.
Verwenden der EntityDataSource -Eigenschaft "Where" zum Filtern von Daten
Öffnen Sie die Seite Students.aspx , die Sie im vorherigen Tutorial erstellt haben. Wie derzeit konfiguriert, zeigt das GridView
Steuerelement auf der Seite alle Namen aus dem Entitätssatz People
an. Sie möchten jedoch nur Kursteilnehmer anzeigen, die Sie finden können, indem Sie Entitäten auswählen Person
, die nicht NULL-Registrierungsdaten haben.
Wechseln Sie zur Entwurfsansicht , und wählen Sie das EntityDataSource
Steuerelement aus. Legen Sie im Fenster Eigenschaften die Eigenschaft Where
auf it.EnrollmentDate is not null
fest.
Die Syntax, die Sie in der Where
-Eigenschaft des -Steuerelements EntityDataSource
verwenden, ist Entity SQL. Entity SQL ähnelt Transact-SQL, wird aber für die Verwendung mit Entitäten und nicht mit Datenbankobjekten angepasst. Im Ausdruck it.EnrollmentDate is not null
stellt das Wort it
einen Verweis auf die von der Abfrage zurückgegebene Entität dar. it.EnrollmentDate
Bezieht sich daher auf die EnrollmentDate
Eigenschaft der Person
Entität, die das EntityDataSource
Steuerelement zurückgibt.
Führen Sie die Seite aus. Die Kursteilnehmerliste enthält jetzt nur Studenten. (Es werden keine Zeilen angezeigt, in denen kein Registrierungsdatum vorhanden ist.)
Verwenden der EntityDataSource -Eigenschaft "OrderBy" zum Bestellen von Daten
Sie möchten auch, dass sich diese Liste in der Namensreihenfolge befindet, wenn sie zum ersten Mal angezeigt wird. Wenn die Seite Students.aspx in der Entwurfsansicht weiterhin geöffnet ist und das EntityDataSource
Steuerelement noch ausgewählt ist, legen Sie im Eigenschaftenfenster die OrderBy-Eigenschaft auf fest it.LastName
.
Führen Sie die Seite aus. Die Kursteilnehmerliste ist jetzt nach Nachnamen sortiert.
Verwenden eines Steuerelementparameters zum Festlegen der "Where"-Eigenschaft
Wie bei anderen Datenquellensteuerelementen können Sie Parameterwerte an die Where
-Eigenschaft übergeben. Auf der Seite Courses.aspx , die Sie in Teil 2 des Tutorials erstellt haben, können Sie diese Methode verwenden, um Kurse anzuzeigen, die der Abteilung zugeordnet sind, die ein Benutzer aus der Dropdownliste auswählt.
Öffnen Sie Courses.aspx , und wechseln Sie zur Entwurfsansicht . Fügen Sie der Seite ein zweites EntityDataSource
Steuerelement hinzu, und nennen Sie es CoursesEntityDataSource
. Verbinden Sie es mit dem SchoolEntities
Modell, und wählen Sie als EntitySetName-Wert ausCourses
.
Klicken Sie im Fenster Eigenschaften auf die Auslassungspunkte im Feld Where-Eigenschaft . (Stellen Sie sicher, dass das CoursesEntityDataSource
Steuerelement weiterhin ausgewählt ist, bevor Sie das Eigenschaftenfenster verwenden.)
Das Dialogfeld Ausdrucks-Editor wird angezeigt. Wählen Sie in diesem Dialogfeld Automatisch den Where-Ausdruck basierend auf den bereitgestellten Parametern generieren aus, und klicken Sie dann auf Parameter hinzufügen. Nennen Sie den Parameter DepartmentID
, wählen Sie Control als Parameterquellwert aus, und wählen Sie DepartmentsDropDownList als ControlID-Wert aus.
Klicken Sie auf Erweiterte Eigenschaften anzeigen, und ändern Sie im Eigenschaftenfenster des Dialogfelds Ausdrucks-Editor die Type
Eigenschaft in Int32
.
Wenn Sie fertig sind, klicken Sie auf OK.
Fügen Sie unterhalb der Dropdownliste der Seite ein GridView
Steuerelement hinzu, und nennen Sie es CoursesGridView
. Verbinden Sie es mit dem CoursesEntityDataSource
Datenquellensteuerelement, klicken Sie auf Schema aktualisieren, klicken Sie auf Spalten bearbeiten, und entfernen Sie die DepartmentID
Spalte. Das GridView
Steuerelementmarkup ähnelt dem folgenden Beispiel.
<asp:GridView ID="CoursesGridView" runat="server" AutoGenerateColumns="False"
DataKeyNames="CourseID" DataSourceID="CoursesEntityDataSource">
<Columns>
<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" />
</Columns>
</asp:GridView>
Wenn der Benutzer die ausgewählte Abteilung in der Dropdownliste ändert, soll sich die Liste der zugeordneten Kurse automatisch ändern. Um dies zu ermöglichen, wählen Sie die Dropdownliste aus, und legen Sie im Fenster Eigenschaften die AutoPostBack
Eigenschaft auf fest True
.
Nachdem Sie nun mit dem Designer fertig sind, wechseln Sie zur Quellansicht , und ersetzen Sie die ConnectionString
Eigenschaften und DefaultContainer
name des CoursesEntityDataSource
Steuerelements durch das ContextTypeName="ContosoUniversity.DAL.SchoolEntities"
-Attribut. Wenn Sie fertig sind, sieht das Markup für das Steuerelement wie im folgenden Beispiel aus.
<asp:EntityDataSource ID="CoursesEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="false"
EntitySetName="Courses"
AutoGenerateWhereClause="true" Where="">
<WhereParameters>
<asp:ControlParameter ControlID="DepartmentsDropDownList" Type="Int32"
Name="DepartmentID" PropertyName="SelectedValue" />
</WhereParameters>
</asp:EntityDataSource>
Führen Sie die Seite aus, und verwenden Sie die Dropdownliste, um verschiedene Abteilungen auszuwählen. Nur Kurse, die von der ausgewählten Abteilung angeboten werden, werden im GridView
Steuerelement angezeigt.
Verwenden der EntityDataSource -Eigenschaft "GroupBy" zum Gruppieren von Daten
Angenommen, die Contoso University möchte einige Statistiken für Studenten auf der Seite "Info" einfügen. Insbesondere soll eine Aufschlüsselung der Schülerzahlen nach dem Datum der Anmeldung angezeigt werden.
Öffnen Sie About.aspx, und ersetzen Sie in der Quellansicht den vorhandenen Inhalt des BodyContent
Steuerelements durch "Student Body Statistics" zwischen h2
Tags:
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>Student Body Statistics</h2>
</asp:Content>
Fügen Sie nach der Überschrift ein EntityDataSource
Steuerelement hinzu, und nennen Sie es StudentStatisticsEntityDataSource
. Verbinden Sie es mit SchoolEntities
, wählen Sie den People
Entitätssatz aus, und lassen Sie das Feld Auswählen im Assistenten unverändert. Legen Sie die folgenden Eigenschaften im Eigenschaftenfenster fest:
- Um nur nach Kursteilnehmern zu filtern, legen Sie die
Where
-Eigenschaft auf festit.EnrollmentDate is not null
. - Um die Ergebnisse nach dem Registrierungsdatum zu gruppieren, legen Sie die
GroupBy
-Eigenschaft auf festit.EnrollmentDate
. - Um das Registrierungsdatum und die Anzahl der Kursteilnehmer auszuwählen, legen Sie die
Select
-Eigenschaft aufit.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents
fest. - Um die Ergebnisse nach dem Registrierungsdatum zu sortieren, legen Sie die
OrderBy
-Eigenschaft auf festit.EnrollmentDate
.
Ersetzen Sie in der Quellansicht die ConnectionString
Eigenschaften und DefaultContainer
durch eine ContextTypeName
Eigenschaft. Das EntityDataSource
Steuerelementmarkup ähnelt nun dem folgenden Beispiel.
<asp:EntityDataSource ID="StudentStatisticsEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="People"
Select="it.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents"
OrderBy="it.EnrollmentDate" GroupBy="it.EnrollmentDate"
Where="it.EnrollmentDate is not null" >
</asp:EntityDataSource>
Die Syntax der Select
Eigenschaften , GroupBy
und Where
ähnelt Transact-SQL mit Ausnahme der it
Schlüsselwort (keyword), die die aktuelle Entität angibt.
Fügen Sie das folgende Markup hinzu, um ein GridView
Steuerelement zum Anzeigen der Daten zu erstellen.
<asp:GridView ID="StudentStatisticsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="StudentStatisticsEntityDataSource">
<Columns>
<asp:BoundField DataField="EnrollmentDate" DataFormatString="{0:d}"
HeaderText="Date of Enrollment"
ReadOnly="True" SortExpression="EnrollmentDate" />
<asp:BoundField DataField="NumberOfStudents" HeaderText="Students"
ReadOnly="True" SortExpression="NumberOfStudents" />
</Columns>
</asp:GridView>
Führen Sie die Seite aus, um eine Liste anzuzeigen, die die Anzahl der Kursteilnehmer nach Demmatrikulationsdatum anzeigt.
Verwenden des QueryExtender-Steuerelements zum Filtern und Sortieren
Das QueryExtender
Steuerelement bietet eine Möglichkeit zum Angeben von Filterung und Sortierung im Markup. Die Syntax ist unabhängig von dem datenbankverwaltungssystem (DBMS), das Sie verwenden. Es ist auch im Allgemeinen unabhängig vom Entity Framework, mit der Ausnahme, dass die Syntax, die Sie für Navigationseigenschaften verwenden, für das Entity Framework eindeutig ist.
In diesem Teil des Tutorials verwenden Sie ein QueryExtender
Steuerelement zum Filtern und Sortieren von Daten, und eines der Order-by-Felder ist eine Navigationseigenschaft.
(Wenn Sie lieber Code anstelle von Markup verwenden möchten, um die Abfragen zu erweitern, die EntityDataSource
automatisch vom Steuerelement generiert werden, können Sie dies tun, indem Sie das QueryCreated
Ereignis behandeln. So erweitert EntityDataSource
das QueryExtender
Steuerelement auch Steuerelementabfragen.)
Öffnen Sie die Seite Courses.aspx , und fügen Sie unter dem Markup, das Sie zuvor hinzugefügt haben, das folgende Markup ein, um eine Überschrift, ein Textfeld zum Eingeben von Suchzeichenfolgen, eine Suchschaltfläche und ein EntityDataSource
Steuerelement zu erstellen, das an den Courses
Entitätssatz gebunden ist.
<h2>Courses by Name</h2>
Enter a course name
<asp:TextBox ID="SearchTextBox" runat="server"></asp:TextBox>
<asp:Button ID="SearchButton" runat="server" Text="Search" />
<br /><br />
<asp:EntityDataSource ID="SearchEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="Courses"
Include="Department" >
</asp:EntityDataSource>
Beachten Sie, dass die EntityDataSource
-Eigenschaft des Steuerelements Include
auf Department
festgelegt ist. In der Datenbank enthält die Course
Tabelle nicht den Abteilungsnamen, sie enthält eine DepartmentID
Fremdschlüsselspalte. Wenn Sie die Datenbank direkt abfragen, müssen Sie die Tabellen und Department
verknüpfen, um den Abteilungsnamen zusammen mit den Course
Kursdaten abzurufen. Indem Sie die Include
-Eigenschaft auf Department
festlegen, geben Sie an, dass das Entity Framework die Arbeit zum Abrufen der zugehörigen Department
Entität ausführen soll, wenn es eine Course
Entität erhält. Die Department
Entität wird dann in der Department
Navigationseigenschaft der Course
Entität gespeichert. (Standardmäßig ruft die SchoolEntities
vom Datenmodell-Designer generierte Klasse verwandte Daten ab, wenn sie benötigt werden, und Sie haben das Datenquellensteuerelement an diese Klasse gebunden, sodass das Festlegen der Include
Eigenschaft nicht erforderlich ist. Das Festlegen verbessert jedoch die Leistung der Seite, da das Entity Framework andernfalls separate Aufrufe an die Datenbank durchführt, um Daten für die Course
Entitäten und die zugehörigen Department
Entitäten abzurufen.)
Fügen Sie nach dem EntityDataSource
soeben erstellten Steuerelement das folgende Markup ein, um ein QueryExtender
Steuerelement zu erstellen, das an dieses EntityDataSource
Steuerelement gebunden ist.
<asp:QueryExtender ID="SearchQueryExtender" runat="server"
TargetControlID="SearchEntityDataSource" >
<asp:SearchExpression SearchType="StartsWith" DataFields="Title">
<asp:ControlParameter ControlID="SearchTextBox" />
</asp:SearchExpression>
<asp:OrderByExpression DataField="Department.Name" Direction="Ascending">
<asp:ThenBy DataField="Title" Direction="Ascending" />
</asp:OrderByExpression>
</asp:QueryExtender>
Das SearchExpression
-Element gibt an, dass Sie Kurse auswählen möchten, deren Titel dem im Textfeld eingegebenen Wert entsprechen. Es werden nur so viele Zeichen verglichen, wie in das Textfeld eingegeben werden, da die SearchType
-Eigenschaft angibt StartsWith
.
Das OrderByExpression
-Element gibt an, dass das Resultset nach Kurstitel innerhalb des Abteilungsnamens sortiert wird. Beachten Sie, wie der Abteilungsname angegeben wird: Department.Name
. Da die Zuordnung zwischen der Course
Entität und der Department
Entität 1:1 ist, enthält die Department
Navigationseigenschaft eine Department
Entität. (Wenn dies eine 1:n-Beziehung wäre, würde die -Eigenschaft eine Auflistung enthalten.) Um den Abteilungsnamen abzurufen, müssen Sie die Name
Eigenschaft der Department
Entität angeben.
Fügen Sie schließlich ein GridView
Steuerelement hinzu, um die Liste der Kurse anzuzeigen:
<asp:GridView ID="SearchGridView" runat="server" AutoGenerateColumns="False"
DataKeyNames="CourseID" DataSourceID="SearchEntityDataSource" AllowPaging="true">
<Columns>
<asp:TemplateField HeaderText="Department">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("Department.Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="CourseID" HeaderText="ID"/>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Credits" HeaderText="Credits" />
</Columns>
</asp:GridView>
Die erste Spalte ist ein Vorlagenfeld, in dem der Abteilungsname angezeigt wird. Der Datenbindungsausdruck gibt genau so an Department.Name
, wie Sie es im QueryExtender
Steuerelement gesehen haben.
Führen Sie die Seite aus. Die anfängliche Anzeige zeigt eine Liste aller Kurse nach Abteilung und dann nach Kurstitel.
Geben Sie ein "m" ein, und klicken Sie auf Suchen , um alle Kurse anzuzeigen, deren Titel mit "m" beginnen (bei der Suche wird die Groß-/Kleinschreibung nicht beachtet).
Verwenden des "Like"-Operators zum Filtern von Daten
Sie können einen Ähnlicheffekt wie die QueryExtender
Suchtypen des Steuerelements StartsWith
, Contains
, und EndsWith
erzielen, indem Sie einen Like
Operator in der -Eigenschaft des EntityDataSource
Steuerelements Where
verwenden. In diesem Teil des Tutorials erfahren Sie, wie Sie den Like
Operator verwenden, um nach einem Kursteilnehmer nach dem Namen zu suchen.
Öffnen Sie Students.aspx in der Quellansicht . Fügen Sie nach dem GridView
Steuerelement das folgende Markup hinzu:
<h2>Find Students by Name</h2>
Enter any part of the name
<asp:TextBox ID="SearchTextBox" runat="server" AutoPostBack="true"></asp:TextBox>
<asp:Button ID="SearchButton" runat="server" Text="Search" />
<br />
<br />
<asp:EntityDataSource ID="SearchEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="People"
Where="it.EnrollmentDate is not null and (it.FirstMidName Like '%' + @StudentName + '%' or it.LastName Like '%' + @StudentName + '%')" >
<WhereParameters>
<asp:ControlParameter ControlID="SearchTextBox" Name="StudentName" PropertyName="Text"
Type="String" DefaultValue="%"/>
</WhereParameters>
</asp:EntityDataSource>
<asp:GridView ID="SearchGridView" runat="server" AutoGenerateColumns="False" DataKeyNames="PersonID"
DataSourceID="SearchEntityDataSource" AllowPaging="true">
<Columns>
<asp:TemplateField HeaderText="Name" SortExpression="LastName, FirstMidName">
<ItemTemplate>
<asp:Label ID="LastNameFoundLabel" runat="server" Text='<%# Eval("LastName") %>'></asp:Label>,
<asp:Label ID="FirstNameFoundLabel" runat="server" Text='<%# Eval("FirstMidName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Enrollment Date" SortExpression="EnrollmentDate">
<ItemTemplate>
<asp:Label ID="EnrollmentDateFoundLabel" runat="server" Text='<%# Eval("EnrollmentDate", "{0:d}") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Dieses Markup ähnelt dem, was Sie zuvor gesehen haben, mit Ausnahme des Where
Eigenschaftswerts. Der zweite Teil des Where
Ausdrucks definiert eine Teilzeichenfolgensuche (LIKE %FirstMidName% or LIKE %LastName%
), die sowohl den Vor- als auch den Nachnamen nach dem im Textfeld eingegebenen Element durchsucht.
Führen Sie die Seite aus. Zunächst werden alle Kursteilnehmer angezeigt, da der Standardwert für den StudentName
Parameter "%" ist.
Geben Sie den Buchstaben "g" in das Textfeld ein, und klicken Sie auf Suchen. Es wird eine Liste von Kursteilnehmern angezeigt, die entweder im Vor- oder Nachnamen ein "g" haben.
Sie haben nun Daten aus einzelnen Tabellen angezeigt, aktualisiert, gefiltert, sortiert und gruppiert. Im nächsten Tutorial beginnen Sie mit der Arbeit mit verwandten Daten (master-Detailszenarien).