Freigeben über


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

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

Implementierung von Table-per-Hierarchy-Vererbung

Im vorherigen Lernprogramm haben Sie mit verwandten Daten gearbeitet, indem Sie Beziehungen hinzufügen und löschen und eine neue Entität hinzufügen, die eine Beziehung zu einer vorhandenen Entität hatte. In diesem Lernprogramm erfahren Sie, wie Sie die Vererbung im Datenmodell implementieren.

In der objektorientierten Programmierung können Sie die Vererbung verwenden, um die Arbeit mit verwandten Klassen zu vereinfachen. Sie könnten z. B. Instructor- und Student-Klassen erstellen, die von einer Person-Basisklasse abgeleitet sind. Sie können dieselben Arten von Vererbungsstrukturen zwischen Entitäten im Entity Framework erstellen.

In diesem Teil des Lernprogramms erstellen Sie keine neuen Webseiten. Stattdessen fügen Sie dem Datenmodell abgeleitete Entitäten hinzu und ändern vorhandene Seiten, um die neuen Entitäten zu verwenden.

Tabellen-pro-Hierarchie- versus Tabellen-pro-Typ-Vererbung

Eine Datenbank kann Informationen zu verwandten Objekten in einer Tabelle oder in mehreren Tabellen speichern. In der Datenbank enthält die SchoolPerson Tabelle beispielsweise Informationen zu Schülern und Kursleitern in einer einzigen Tabelle. Einige der Spalten gelten nur für Kursleiter (HireDate), einige nur für Schüler (EnrollmentDate) und einige für beide (LastName, FirstName).

Bild11

Sie können das Entity Framework so konfigurieren, dass es die Entitäten Instructor und Student erstellt, die von der Entität Person erben. Dieses Muster zum Generieren einer Entitätsvererbungsstruktur aus einer einzelnen Datenbanktabelle wird als TPH-Vererbung (Table-per-Hierarchy ) bezeichnet.

Für Kurse verwendet die School Datenbank ein anderes Muster. Onlinekurse und Vor-Ort-Kurse werden in separaten Tabellen gespeichert, von denen jeder über einen Fremdschlüssel verfügt, der auf die Course Tabelle verweist. Informationen, die für beide Kurstypen gemeinsam sind, werden nur in der Course Tabelle gespeichert.

Bild12

Sie können das Entity Framework-Datenmodell so konfigurieren, dass OnlineCourse und OnsiteCourse Entitäten von der Course Entität erben. Dieses Muster, eine Entitätsvererbungsstruktur aus separaten Tabellen für jeden Typ zu generieren, wobei jede separate Tabelle, die auf eine Tabelle verweist, die Daten speichert, die allen Typen gemeinsam sind, wird als "Tabelle pro Typ " (TPT)-Vererbung bezeichnet.

TPH-Vererbungsmuster bieten in der Regel eine bessere Leistung im Entity Framework als TPT-Vererbungsmuster, da TPT-Muster zu komplexen Verknüpfungsabfragen führen können. In dieser Schritt-für-Schritt-Anleitung wird veranschaulicht, wie die TPH-Vererbung implementiert wird. Dazu führen Sie die folgenden Schritte aus:

  • Erstellen Sie die Instructor und Student Entitätstypen, die von Person abgeleitet sind.
  • Verschieben Sie Eigenschaften, die sich auf die abgeleiteten Entitäten aus der Person Entität beziehen, in die abgeleiteten Entitäten.
  • Legen Sie Einschränkungen für Eigenschaften in den abgeleiteten Typen fest.
  • Legen Sie die Person Entität als abstrakte Entität fest.
  • Ordnen Sie jede abgeleitete Entität der Person Tabelle mit einer Bedingung zu, die angibt, wie eine Person Zeile den abgeleiteten Typ darstellt.

Hinzufügen von Kursleiter- und Kursteilnehmerentitäten

Öffnen Sie die Datei SchoolModel.edmx, klicken Sie mit der rechten Maustaste auf einen nicht belegten Bereich im Designer, wählen Sie "Hinzufügen" und dann "Entität" aus.

Bild01

Benennen Sie im Dialogfeld Entität hinzufügen die Entität Instructor , und legen Sie die Basistypoption auf Person.

Bild02

Klicke auf OK. Der Designer erstellt eine Instructor Entität, die von der Person Entität abgeleitet wird. Die neue Entität verfügt noch nicht über Eigenschaften.

Bild03

Wiederholen Sie die Vorgehensweise, um eine Student-Entität zu erstellen, die ebenfalls von Person.

Nur Instruktoren haben Einstellungsdaten, daher müssen Sie diese Eigenschaft von der Person Entität zur Instructor Entität verschieben. Klicken Sie mit der rechten Maustaste auf die Person Entität, klicken Sie auf die HireDate Eigenschaft, und klicken Sie dann auf "Ausschneiden". Klicken Sie dann mit der rechten Maustaste auf "Eigenschaften" in der Instructor Entität, und klicken Sie dann auf "Einfügen".

Bild04

Das Einstellungsdatum einer Instructor Entität darf nicht null sein. Klicken Sie mit der rechten Maustaste auf die HireDate Eigenschaft, klicken Sie auf "Eigenschaften", und ändern Sie dann im Nullable"-Fenster in False.

Bild05

Wiederholen Sie die Prozedur, um die EnrollmentDate-Eigenschaft von der Person-Entität zur Student-Entität zu verschieben. Stellen Sie sicher, dass Sie Nullable auch auf False für die EnrollmentDate Eigenschaft festlegen.

Da eine Person Entität nur über die Eigenschaften verfügt, die gemeinsam mit Instructor und Student Entitäten sind (abgesehen von Navigationseigenschaften, die Sie nicht verschieben), kann die Entität nur als Basisentität in der Vererbungsstruktur verwendet werden. Daher müssen Sie sicherstellen, dass sie nie als unabhängige Entität behandelt wird. Klicken Sie mit der rechten Maustaste auf die Person Entität, wählen Sie "Eigenschaften" aus, und ändern Sie dann im Fenster "Eigenschaften " den Wert der abstrakten Eigenschaft in "True".

Image06

Zuordnen der Lehrer- und Kursteilnehmerentitäten zur Personentabelle

Jetzt müssen Sie dem Entity Framework mitteilen, wie zwischen Instructor Entitäten und Student Entitäten in der Datenbank unterschieden werden kann.

Klicken Sie mit der rechten Maustaste auf die Instructor Entität, und wählen Sie "Tabellenzuordnung" aus. Klicken Sie im Fenster "Zuordnungsdetails " auf " Tabelle oder Ansicht hinzufügen ", und wählen Sie "Person" aus.

Bild07

Klicken Sie auf "Bedingung hinzufügen", und wählen Sie dann "HireDate" aus.

Bild09

Operator auf Is und Value / Property auf Not Null ändern.

Bild10

Wiederholen Sie die Prozedur für die Students Entität, die angibt, dass diese Entität der Person Tabelle zugeordnet ist, wenn die EnrollmentDate Spalte nicht NULL ist. Speichern und schließen Sie dann das Datenmodell.

Erstellen Sie das Projekt, um die neuen Entitäten als Klassen zu erstellen und im Designer verfügbar zu machen.

Verwenden der Kursleiter- und Kursteilnehmerentitäten

Wenn Sie die Webseiten erstellt haben, die mit Kursteilnehmer- und Kursleiterdaten arbeiten, haben Sie sie an den Person-Entitätssatz gebunden und nach der HireDate- oder EnrollmentDate-Eigenschaft gefiltert, um die zurückgegebenen Daten auf Kursteilnehmer oder Kursleiter einzuschränken. Wenn Sie nun jedoch jedes Datenquellensteuerelement an den Person Entitätssatz binden, können Sie angeben, dass nur Student oder Instructor Entitätstypen ausgewählt werden sollen. Da das Entity Framework weiß, wie Kursteilnehmer und Kursleiter im Person Entitätssatz unterschieden werden können, können Sie die Eigenschaftseinstellungen, die Sie Where manuell eingegeben haben, um die Unterscheidung zu ermöglichen, entfernen.

Im Visual Studio Designer können Sie den Entitätstyp angeben, den ein EntityDataSource Steuerelement im Dropdownfeld "EntityTypeFilter " des Configure Data Source Assistenten auswählen soll, wie im folgenden Beispiel gezeigt.

Bild13

Und im Eigenschaftenfenster können Sie Klauselwerte entfernen Where , die nicht mehr benötigt werden, wie im folgenden Beispiel gezeigt.

Bild14

Da Sie jedoch das Markup für EntityDataSource Steuerelemente für die Verwendung des ContextTypeName Attributs geändert haben, können Sie den Assistenten zum Konfigurieren der Datenquelle nicht für EntityDataSource bereits erstellte Steuerelemente ausführen. Daher nehmen Sie die erforderlichen Änderungen vor, indem Sie stattdessen Markup ändern.

Öffnen Sie die Students.aspx Seite. Entfernen Sie im StudentsEntityDataSource Steuerelement das Where Attribut, und fügen Sie ein EntityTypeFilter="Student" Attribut hinzu. Das Markup ähnelt nun dem folgenden Beispiel:

<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
        EntitySetName="People" EntityTypeFilter="Student"
        Include="StudentGrades"
        EnableDelete="True" EnableUpdate="True" 
        OrderBy="it.LastName" >
    </asp:EntityDataSource>

Durch Festlegen des EntityTypeFilter Attributs wird sichergestellt, dass das EntityDataSource Steuerelement nur den angegebenen Entitätstyp auswählt. Wenn Sie sowohl die Entitätstypen Student als auch Instructor abrufen möchten, würden Sie dieses Attribut nicht festlegen. (Sie haben die Möglichkeit, mehrere Entitätstypen nur mit einem EntityDataSource Steuerelement abzurufen, wenn Sie das Steuerelement für den schreibgeschützten Datenzugriff verwenden. Wenn Sie ein EntityDataSource Steuerelement verwenden, um Entitäten einzufügen, zu aktualisieren oder zu löschen, und wenn die Entität festgelegt ist, an die es gebunden ist, mehrere Typen enthalten kann, können Sie nur mit einem Entitätstyp arbeiten, und Sie müssen dieses Attribut festlegen.)

Wiederholen Sie die Prozedur für das SearchEntityDataSource Steuerelement, mit der Ausnahme, dass nur der Teil des Where Attributs entfernt wird, der Entitäten Student auswählt, anstatt die Eigenschaft vollständig zu entfernen. Das öffnende Tag des Steuerelements ähnelt nun dem folgenden Beispiel:

<asp:EntityDataSource ID="SearchEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
        EntitySetName="People" EntityTypeFilter="Student"
        Where="it.FirstMidName Like '%' + @StudentName + '%' or it.LastName Like '%' + @StudentName + '%'" >

Führen Sie die Seite aus, um zu überprüfen, ob sie wie zuvor funktioniert.

Bild 15

Aktualisieren Sie die folgenden Seiten, die Sie in früheren Lernprogrammen erstellt haben, damit sie die neuen Student Und Instructor Entitäten anstelle von Person Entitäten verwenden, und führen Sie sie aus, um sicherzustellen, dass sie wie zuvor funktionieren:

  • Fügen Sie in StudentsAdd.aspx zum Steuerelement StudentsEntityDataSourceEntityTypeFilter="Student" hinzu. Das Markup ähnelt nun dem folgenden Beispiel:

    <asp:EntityDataSource ID="StudentsEntityDataSource" runat="server" 
            ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
            EntitySetName="People" EntityTypeFilter="Student"
            EnableInsert="True" 
        </asp:EntityDataSource>
    

    Bild16

  • Fügen Sie in About.aspx das EntityTypeFilter="Student"-Steuerelement hinzu und entfernen Sie Where="it.EnrollmentDate is not null" aus StudentStatisticsEntityDataSource. Das Markup ähnelt nun dem folgenden Beispiel:

    <asp:EntityDataSource ID="StudentStatisticsEntityDataSource" runat="server" 
            ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
            EntitySetName="People" EntityTypeFilter="Student"
            Select="it.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents"
            OrderBy="it.EnrollmentDate" GroupBy="it.EnrollmentDate" >
        </asp:EntityDataSource>
    

    Bild17

  • Fügen Sie in Instructors.aspx und InstructorsCourses.aspxEntityTypeFilter="Instructor" zum InstructorsEntityDataSource-Steuerelement hinzu, und entfernen Sie Where="it.HireDate is not null". Das Markup in Instructors.aspx ähnelt nun dem folgenden Beispiel:

    <asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" 
                ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="false"
                EntitySetName="People" EntityTypeFilter="Instructor" 
                Include="OfficeAssignment" 
                EnableUpdate="True">
            </asp:EntityDataSource>
    

    Bild18

    Das Markup in InstructorsCourses.aspx ähnelt nun dem folgenden Beispiel:

    <asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" 
            ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
            EntitySetName="People" EntityTypeFilter="Instructor" 
            Select="it.LastName + ',' + it.FirstMidName AS Name, it.PersonID">
        </asp:EntityDataSource>
    

    Bild 19

Aufgrund dieser Änderungen haben Sie die Aufrechterhaltung der Contoso University-Anwendung auf verschiedene Arten verbessert. Sie haben die Auswahl- und Validierungslogik aus der UI-Ebene (.aspx Markup) verschoben und zu einem integralen Bestandteil der Datenzugriffsebene gemacht. Dadurch können Sie den Anwendungscode vor Änderungen isolieren, die Sie in Zukunft am Datenbankschema oder dem Datenmodell vornehmen können. Sie könnten z. B. entscheiden, dass Schüler/Studenten als Lehrerhilfen eingestellt werden und daher ein Einstellungsdatum erhalten würden. Anschließend können Sie eine neue Eigenschaft hinzufügen, um Kursteilnehmer von Kursleitern zu unterscheiden und das Datenmodell zu aktualisieren. Es muss kein Code in der Webanwendung geändert werden, es sei denn, Sie wollten ein Einstellungsdatum für Kursteilnehmer anzeigen. Ein weiterer Vorteil beim Hinzufügen Instructor und Student Entitäten besteht darin, dass Ihr Code leichter verständlich ist, als wenn er auf Objekte verweist Person , die tatsächlich Kursteilnehmer oder Kursleiter waren.

Sie haben nun eine Möglichkeit gesehen, ein Vererbungsmuster im Entity Framework zu implementieren. Im folgenden Lernprogramm erfahren Sie, wie Sie gespeicherte Prozeduren verwenden, um mehr Kontrolle darüber zu haben, wie das Entity Framework auf die Datenbank zugreift.