Share via


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

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.

Implementieren der "Tabelle pro Hierarchie"-Vererbung

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

Bei der objektorientierten Programmierung können Sie vererbung verwenden, um das Arbeiten mit verwandten Klassen zu vereinfachen. Sie können beispielsweise klassen und Student erstellenInstructor, 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 Tutorials 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.

Vererbung von Tabellen pro Hierarchie im Vergleich zur Vererbung von Tabellen pro Typ

Eine Datenbank kann Informationen zu verwandten Objekten in einer Oder in mehreren Tabellen speichern. In der School Datenbank enthält die Person Tabelle beispielsweise Informationen zu Kursteilnehmern und Dozenten in einer einzelnen Tabelle. Einige der Spalten gelten nur für Dozenten (HireDate), einige nur für Schüler (EnrollmentDate) und einige für beide (LastName, FirstName).

image11

Sie können Entity Framework so konfigurieren, dass Entitäten und Student erstellt Instructor werden, die von der Entität erbenPerson. 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, die jeweils einen Fremdschlüssel haben, der auf die Course Tabelle verweist. Informationen, die für beide Kurstypen gemeinsam sind, werden nur in der Course Tabelle gespeichert.

image12

Sie können das Entity Framework-Datenmodell so konfigurieren, dass OnlineCourse entitäten und OnsiteCourse von der Entität erben Course . Dieses Muster zum Generieren einer Entitätsvererbungsstruktur aus separaten Tabellen für jeden Typ, wobei jede separate Tabelle auf eine Tabelle verweist, in der alle Typen gemeinsame Daten speichert, wird als TPT-Vererbung ( Table Per Type ) bezeichnet.

TPH-Vererbungsmuster bieten im Allgemeinen eine bessere Leistung im Entity Framework als TPT-Vererbungsmuster, da TPT-Muster zu komplexen Joinabfragen führen können. In dieser exemplarischen Vorgehensweise wird veranschaulicht, wie TPH-Vererbung implementiert wird. Führen Sie dazu die folgenden Schritte aus:

  • Erstellen Sie Instructor Entitätstypen und Student , die von abgeleitet werden Person.
  • Verschieben Sie Eigenschaften, die sich auf die abgeleiteten Entitäten beziehen, von der Person Entität 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 bestimmt wird, ob eine Person Zeile diesen abgeleiteten Typ darstellt.

Hinzufügen von Dozenten- und Studentenentitä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.

image01

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

image02

Klicken Sie 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.

image03

Wiederholen Sie die Prozedur, um eine Student Entität zu erstellen, die ebenfalls von abgeleitet wird Person.

Nur Dozenten verfügen über Einstellungsdaten, sodass Sie diese Eigenschaft von der Person Entität in die Instructor Entität verschieben müssen. Klicken Sie in der Person Entität mit der rechten Maustaste auf die HireDate Eigenschaft, und klicken Sie auf Ausschneiden. Klicken Sie dann mit der rechten Maustaste in der Instructor Entität auf Eigenschaften, und klicken Sie auf Einfügen.

image04

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 Nullable dann im Fenster Eigenschaften in False.

image05

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

Da eine Person Entität nun nur über die Eigenschaften verfügt, die für Entitäten und Student gelten Instructor (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 niemals 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 von Dozenten- und Studentenentitäten zur Personentabelle

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

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

image07

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

image09

Ändern Sie operator in Is und Value/Property in Not Null.

image10

Wiederholen Sie die Prozedur für die Students Entität, und geben Sie an, dass diese Entität der Person Tabelle zugeordnet wird, 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 Entitäten "Dozent" und "Student"

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

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.

image13

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

image14

Da Sie jedoch das Markup für EntityDataSource Steuerelemente geändert haben, um das ContextTypeName -Attribut zu verwenden, können Sie den Assistenten zum Konfigurieren von Datenquellen nicht für EntityDataSource Steuerelemente ausführen, die Sie bereits erstellt haben. Daher nehmen Sie die erforderlichen Änderungen vor, indem Sie stattdessen das Markup ändern.

Öffnen Sie die Seite Students.aspx . Entfernen Sie im StudentsEntityDataSource -Steuerelement das Where Attribut, und fügen Sie ein Attribut hinzu EntityTypeFilter="Student" . 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 entitätstypen als auch StudentInstructor entitätstypen abrufen möchten, würden Sie dieses Attribut nicht festlegen. (Sie haben nur die Möglichkeit, mehrere Entitätstypen mit einem EntityDataSource Steuerelement abzurufen, wenn Sie das Steuerelement für den schreibgeschützten Datenzugriff verwenden. Wenn Sie ein EntityDataSource Steuerelement zum Einfügen, Aktualisieren oder Löschen von Entitäten verwenden und wenn die Entität, an die sie 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, außer entfernen Sie nur den Teil des Where Attributs, das Entitäten Student auswählt, anstatt die Eigenschaft ganz 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 sicherzustellen, dass sie weiterhin wie zuvor funktioniert.

image15

Aktualisieren Sie die folgenden Seiten, die Sie in früheren Tutorials erstellt haben, sodass sie die neuen Student Entitäten und Instructor anstelle von Person Entitäten verwenden, und führen Sie sie dann aus, um zu überprüfen, ob sie wie zuvor funktionieren:

  • Fügen Sie in StudentsAdd.aspx dem StudentsEntityDataSource -Steuerelement hinzuEntityTypeFilter="Student". 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>
    

    image16

  • Fügen Sie in About.aspx dem StudentStatisticsEntityDataSource -Steuerelement hinzuEntityTypeFilter="Student", und entfernen Sie Where="it.EnrollmentDate is not null". 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>
    

    image17

  • Fügen Sie in Instructors.aspx und InstructorsCourses.aspx dem InstructorsEntityDataSource Steuerelement hinzuEntityTypeFilter="Instructor", 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>
    

    image18

    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>
    

    image19

Als Ergebnis dieser Änderungen haben Sie die Wartbarkeit der Contoso University-Anwendung auf verschiedene Weise verbessert. Sie haben die Auswahl- und Validierungslogik aus der UI-Ebene (.aspx-Markup ) verschoben und zu einem integralen Bestandteil der Datenzugriffsebene gemacht. Dies hilft, Ihren Anwendungscode von Änderungen zu isolieren, die Sie in Zukunft am Datenbankschema oder Datenmodell vornehmen könnten. Sie könnten z. B. entscheiden, dass Schüler*innen als Lehrerhilfen eingestellt werden und daher einen Einstellungstermin erhalten. Sie können dann eine neue Eigenschaft hinzufügen, um Schüler von Kursleitern zu unterscheiden und das Datenmodell zu aktualisieren. Es muss sich kein Code in der Webanwendung ändern, es sei denn, Sie möchten ein Einstellungsdatum für Studenten anzeigen. Ein weiterer Vorteil des Hinzufügens Instructor von Entitäten und Student besteht darin, dass Ihr Code leichter verständlich ist, als wenn er auf Person Objekte verweist, die tatsächlich Schüler oder Dozenten waren.

Sie haben nun eine Möglichkeit zum Implementieren eines Vererbungsmusters im Entity Framework kennengelernt. Im folgenden Tutorial erfahren Sie, wie Sie gespeicherte Prozeduren verwenden, um mehr Kontrolle darüber zu haben, wie Entity Framework auf die Datenbank zugreift.