Wprowadzenie z programem Entity Framework 4.0 Database First i ASP.NET 4 Web Forms — część 6
Autor : Tom Dykstra
Przykładowa aplikacja internetowa Contoso University pokazuje, jak tworzyć aplikacje ASP.NET Web Forms przy użyciu platform Entity Framework 4.0 i Visual Studio 2010. Aby uzyskać informacje na temat serii samouczków, zobacz pierwszy samouczek z serii
Implementowanie dziedziczenia tabeli na hierarchię
W poprzednim samouczku pracowaliśmy z powiązanymi danymi przez dodanie i usunięcie relacji oraz dodanie nowej jednostki, która miała relację z istniejącą jednostką. W tym samouczku pokazano, jak zaimplementować dziedziczenie w modelu danych.
W programowaniu obiektowym można użyć dziedziczenia, aby ułatwić pracę z powiązanymi klasami. Można na przykład utworzyć Instructor
klasy i Student
pochodzące z klasy bazowej Person
. Można utworzyć te same rodzaje struktur dziedziczenia między jednostkami w programie Entity Framework.
W tej części samouczka nie utworzysz żadnych nowych stron sieci Web. Zamiast tego dodasz jednostki pochodne do modelu danych i zmodyfikujesz istniejące strony, aby używać nowych jednostek.
Dziedziczenie tabeli na hierarchię w porównaniu z dziedziczeniem tabeli na typ
Baza danych może przechowywać informacje o powiązanych obiektach w jednej tabeli lub w wielu tabelach. Na przykład w School
bazie danych Person
tabela zawiera informacje o uczniach i instruktorach w jednej tabeli. Niektóre kolumny dotyczą tylko instruktorów (HireDate
), niektórych tylko dla uczniów (EnrollmentDate
), a niektóre do obu (LastName
, FirstName
).
Możesz skonfigurować program Entity Framework do tworzenia Instructor
jednostek i Student
dziedziczyjących po jednostce Person
. Ten wzorzec generowania struktury dziedziczenia jednostki z pojedynczej tabeli bazy danych jest nazywany dziedziczeniem TPH ( table-per-hierarchy ).
W przypadku kursów School
baza danych używa innego wzorca. Kursy online i kursy lokalne są przechowywane w osobnych tabelach, z których każdy ma klucz obcy wskazujący tabelę Course
. Informacje wspólne dla obu typów kursów są przechowywane tylko w Course
tabeli.
Model danych programu Entity Framework można skonfigurować tak, OnlineCourse
aby jednostki i OnsiteCourse
dziedziczyły po jednostce Course
. Ten wzorzec generowania struktury dziedziczenia jednostki z oddzielnych tabel dla każdego typu, z każdą oddzielną tabelą odwołującą się z powrotem do tabeli, która przechowuje dane wspólne dla wszystkich typów, jest nazywana tabelą na dziedziczenie typu (TPT).
Wzorce dziedziczenia TPH zwykle zapewniają lepszą wydajność w programie Entity Framework niż wzorce dziedziczenia TPT, ponieważ wzorce TPT mogą powodować złożone zapytania sprzężenia. W tym przewodniku pokazano, jak zaimplementować dziedziczenie TPH. W tym celu należy wykonać następujące czynności:
- Utwórz
Instructor
typy jednostek iStudent
pochodzące z klasyPerson
. - Przenieś właściwości dotyczące jednostek pochodnych z
Person
jednostki do jednostek pochodnych. - Ustawianie ograniczeń dotyczących właściwości w typach pochodnych.
Person
Ustaw jednostkę jako abstrakcyjną.- Zamapuj
Person
każdą jednostkę pochodną na tabelę przy użyciu warunku określającego sposób określaniaPerson
, czy wiersz reprezentuje ten typ pochodny.
Dodawanie jednostek instruktora i ucznia
Otwórz plik SchoolModel.edmx , kliknij prawym przyciskiem myszy obszar niezakształcony w projektancie, wybierz polecenie Dodaj, a następnie wybierz pozycję Jednostka.
W oknie dialogowym Dodawanie jednostkiInstructor
nadaj jednostce nazwę i ustaw jej opcję Typ podstawowy na Person
.
Kliknij przycisk OK. Projektant tworzy jednostkę Instructor
, która pochodzi od Person
jednostki. Nowa jednostka nie ma jeszcze żadnych właściwości.
Powtórz procedurę Student
, aby utworzyć jednostkę, która również pochodzi z klasy Person
.
Tylko instruktorzy mają daty zatrudnienia, więc musisz przenieść ten obiekt z Person
jednostki do Instructor
jednostki. W jednostce Person
kliknij prawym przyciskiem HireDate
myszy właściwość i kliknij polecenie Wytnij. Następnie kliknij prawym przyciskiem myszy pozycję Właściwości w jednostce Instructor
, a następnie kliknij polecenie Wklej.
Data Instructor
zatrudnienia jednostki nie może mieć wartości null. Kliknij prawym przyciskiem myszy HireDate
właściwość, kliknij polecenie Właściwości, a następnie w oknie Właściwości zmień wartość Nullable
na False
.
Powtórz procedurę, aby przenieść EnrollmentDate
właściwość z Person
jednostki do Student
jednostki. Upewnij się, że dla właściwości ustawiono EnrollmentDate
również wartość .Nullable
False
Teraz, gdy Person
jednostka ma tylko właściwości wspólne dla Instructor
jednostek i Student
(oprócz właściwości nawigacji, które nie są przenoszone), jednostka może być używana tylko jako jednostka podstawowa w strukturze dziedziczenia. Dlatego należy upewnić się, że nigdy nie jest traktowana jako niezależna jednostka. Kliknij prawym przyciskiem myszy Person
jednostkę, wybierz pozycję Właściwości, a następnie w oknie Właściwości zmień wartość właściwości Abstract na True.
Mapowanie jednostek instruktora i ucznia na tabelę osób
Teraz musisz poinformować program Entity Framework, jak rozróżniać Instructor
jednostki i Student
w bazie danych.
Kliknij prawym przyciskiem myszy Instructor
jednostkę i wybierz polecenie Mapowanie tabeli. W oknie Szczegóły mapowania kliknij pozycję Dodaj tabelę lub widok i wybierz pozycję Osoba.
Kliknij pozycję Dodaj warunek, a następnie wybierz pozycję HireDate.
Zmień operator na Is i Value/Property na Not Null.
Powtórz procedurę Students
dla jednostki, określając, że ta jednostka jest mapowana na tabelę Person
, gdy kolumna EnrollmentDate
nie ma wartości null. Następnie zapisz i zamknij model danych.
Skompiluj projekt, aby utworzyć nowe jednostki jako klasy i udostępnić je w projektancie.
Korzystanie z jednostek instruktora i ucznia
Po utworzeniu stron internetowych, które współpracują z danymi uczniów i instruktorów, dane są zbierane do Person
zestawu jednostek i filtrowane według HireDate
właściwości lub EnrollmentDate
w celu ograniczenia zwracanych danych do uczniów lub instruktorów. Jednak teraz, gdy powiążesz każdą kontrolę źródła danych z zestawem Person
jednostek, możesz określić, że należy wybrać tylko Student
typy jednostek lub Instructor
typy jednostek. Ponieważ platforma Entity Framework wie, jak rozróżniać uczniów i instruktorów w Person
zestawie jednostek, możesz usunąć Where
wprowadzone ręcznie ustawienia właściwości, aby to zrobić.
W programie Visual Studio Projektant można określić typ jednostki, którą kontrolka EntityDataSource
powinna wybrać w polu Configure Data Source
listy rozwijanej EntityTypeFilter kreatora, jak pokazano w poniższym przykładzie.
W oknie Właściwości można usunąć Where
wartości klauzul, które nie są już potrzebne, jak pokazano w poniższym przykładzie.
Jednak ze względu na to, że zmieniono znaczniki dla EntityDataSource
kontrolek tak, aby korzystały z atrybutu ContextTypeName
, nie można uruchomić Kreatora konfigurowania źródła danych dla EntityDataSource
kontrolek, które zostały już utworzone. W związku z tym należy wprowadzić wymagane zmiany, zmieniając zamiast tego znaczniki.
Otwórz stronę Students.aspx . W kontrolce StudentsEntityDataSource
usuń Where
atrybut i dodaj EntityTypeFilter="Student"
atrybut. Znaczniki będą teraz podobne do następującego przykładu:
<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>
Ustawienie atrybutu EntityTypeFilter
gwarantuje, że kontrolka EntityDataSource
wybierze tylko określony typ jednostki. Jeśli chcesz pobrać typy jednostek Student
i , Instructor
nie ustawisz tego atrybutu. (Istnieje możliwość pobierania wielu typów jednostek z jedną EntityDataSource
kontrolką tylko wtedy, gdy używasz kontrolki na potrzeby dostępu do danych tylko do odczytu. Jeśli używasz EntityDataSource
kontrolki do wstawiania, aktualizowania lub usuwania jednostek, a jeśli zestaw jednostek jest powiązany, może zawierać wiele typów, możesz pracować tylko z jednym typem jednostki i musisz ustawić ten atrybut).
Powtórz procedurę dla kontrolki SearchEntityDataSource
, z wyjątkiem usuwania tylko części atrybutu Where
, który wybiera Student
jednostki zamiast całkowicie usuwać właściwość. Tag otwierający kontrolki będzie teraz podobny do następującego przykładu:
<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 + '%'" >
Uruchom stronę, aby sprawdzić, czy nadal działa tak, jak wcześniej.
Zaktualizuj następujące strony utworzone we wcześniejszych samouczkach, aby korzystały z nowych Student
jednostek i Instructor
zamiast Person
jednostek, a następnie uruchom je, aby sprawdzić, czy działają tak jak wcześniej:
W obszarze StudentsAdd.aspx dodaj
EntityTypeFilter="Student"
do kontrolkiStudentsEntityDataSource
. Znaczniki będą teraz podobne do następującego przykładu:<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server" ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" EntitySetName="People" EntityTypeFilter="Student" EnableInsert="True" </asp:EntityDataSource>
W pliku About.aspx dodaj
EntityTypeFilter="Student"
element do kontrolkiStudentStatisticsEntityDataSource
i usuń elementWhere="it.EnrollmentDate is not null"
. Znaczniki będą teraz podobne do następującego przykładu:<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>
W obszarze Instructors.aspx i InstructorsCourses.aspx dodaj
EntityTypeFilter="Instructor"
element do kontrolkiInstructorsEntityDataSource
i usuń elementWhere="it.HireDate is not null"
. Znaczniki w pliku Instructors.aspx są teraz podobne do następującego przykładu:<asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="false" EntitySetName="People" EntityTypeFilter="Instructor" Include="OfficeAssignment" EnableUpdate="True"> </asp:EntityDataSource>
Znaczniki w pliku InstructorsCourses.aspx będą teraz podobne do następującego przykładu:
<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>
W wyniku tych zmian poprawiliśmy łatwość konserwacji aplikacji Contoso University na kilka sposobów. Przeniesiono logikę wyboru i weryfikacji z warstwy interfejsu użytkownika (znaczniki aspx ) i uczyniono ją integralną częścią warstwy dostępu do danych. Pomaga to odizolować kod aplikacji od zmian, które mogą zostać wprowadzone w przyszłości do schematu bazy danych lub modelu danych. Można na przykład zdecydować, że uczniowie mogą zostać zatrudnieni jako pomoc dla nauczycieli i w związku z tym otrzymać datę zatrudnienia. Następnie można dodać nową właściwość, aby odróżnić uczniów od instruktorów i zaktualizować model danych. Nie trzeba zmieniać kodu w aplikacji internetowej, z wyjątkiem sytuacji, w której chcesz wyświetlić datę zatrudnienia dla uczniów. Kolejną zaletą dodawania Instructor
jednostek i Student
jest to, że kod jest bardziej czytelny niż wtedy, gdy odniósł się do Person
obiektów, które były rzeczywiście uczniami lub instruktorami.
Wiesz już, jak zaimplementować wzorzec dziedziczenia w programie Entity Framework. W poniższym samouczku dowiesz się, jak używać procedur składowanych, aby mieć większą kontrolę nad sposobem uzyskiwania dostępu do bazy danych przez program Entity Framework.