Začínáme se službou Entity Framework 4.0 Database First a ASP.NET 4 Web Forms – část 6
Ukázková webová aplikace Contoso University ukazuje, jak vytvářet ASP.NET Web Forms aplikace pomocí entity frameworku 4.0 a sady Visual Studio 2010. Informace o sérii kurzů najdete v prvním kurzu v této řadě.
Implementace dědičnosti tabulek na hierarchii
V předchozím kurzu jste se souvisejícími daty pracovali přidáním a odstraněním relací a přidáním nové entity, která měla relaci k existující entitě. V tomto kurzu se dozvíte, jak implementovat dědičnost v datovém modelu.
V objektově orientovaném programování můžete pomocí dědičnosti usnadnit práci se souvisejícími třídami. Můžete například vytvořit Instructor
třídy a Student
, které jsou odvozeny ze Person
základní třídy. Stejné druhy struktur dědičnosti můžete vytvořit mezi entitami v Entity Frameworku.
V této části kurzu nebudete vytvářet žádné nové webové stránky. Místo toho přidáte odvozené entity do datového modelu a upravíte existující stránky tak, aby používaly nové entity.
Dědičnost tabulky na hierarchii versus dědičnost typu tabulky
Databáze může ukládat informace o souvisejících objektech v jedné tabulce nebo ve více tabulkách. V databázi Person
například School
tabulka obsahuje informace o studentech i vyučujícím v jedné tabulce. Některé sloupce platí pouze pro instruktory (HireDate
), jiné pouze pro studenty (EnrollmentDate
) a některé pro oba (LastName
, FirstName
).
Entity Framework můžete nakonfigurovat tak, aby vytvářel Instructor
Student
a entity, které dědí z Person
entity. Tento model generování struktury dědičnosti entit z jedné databázové tabulky se nazývá dědičnost TPH (table-per-hierarchy ).
Pro kurzy School
používá databáze jiný vzor. Online kurzy a kurzy na místě jsou uložené v samostatných tabulkách, z nichž každá má cizí klíč, který odkazuje na Course
tabulku. Informace společné pro oba typy kurzů jsou uloženy pouze v tabulce Course
.
Datový model Entity Framework můžete nakonfigurovat tak, aby OnlineCourse
entity a OnsiteCourse
dědily Course
z entity. Tento model generování struktury dědičnosti entit ze samostatných tabulek pro každý typ, přičemž každá samostatná tabulka odkazuje zpět na tabulku, která ukládá data společná pro všechny typy, se nazývá dědičnost typu (TPT ).
Vzory dědičnosti TPH obecně poskytují v Entity Frameworku lepší výkon než vzory dědičnosti TPT, protože vzory TPT mohou vést ke složitým dotazům spojení. Tento návod ukazuje, jak implementovat dědičnost TPH. Provedete to následujícím postupem:
- Vytvoření
Instructor
aStudent
typy entit, které jsou odvozeny zPerson
. - Přesuňte vlastnosti, které se týkají odvozených entit, z
Person
entity do odvozených entit. - Nastavte omezení vlastností v odvozených typech.
- Nastavte entitu
Person
jako abstraktní entitu. - Namapujte každou odvozenou entitu
Person
na tabulku s podmínkou, která určuje, jak určit, zdaPerson
řádek představuje tento odvozený typ.
Přidání entit instruktora a studenta
Otevřete soubor SchoolModel.edmx , klikněte pravým tlačítkem na neobsazenou oblast v návrháři, vyberte Přidat a pak vyberte Entita.
V dialogovém okně Přidat entitu pojmenujte entitu Instructor
a nastavte její možnost Základní typ na Person
.
Klikněte na OK. Návrhář vytvoří entitu Instructor
, která je odvozena z Person
entity. Nová entita ještě nemá žádné vlastnosti.
Opakováním postupu vytvořte entitu Student
, která je také odvozena z Person
.
Data přijetí mají jenom instruktoři, takže tuto vlastnost musíte přesunout z Person
entity do Instructor
entity. V entitě Person
klikněte pravým tlačítkem na HireDate
vlastnost a klikněte na Vyjmout. Potom v entitě Instructor
klikněte pravým tlačítkem na Vlastnosti a klikněte na Vložit.
Datum Instructor
přijetí entity nemůže být null. Klikněte pravým tlačítkem na HireDate
vlastnost, klikněte na Vlastnosti a pak v okně Vlastnosti změňte Nullable
na False
.
Opakováním postupu přesuňte EnrollmentDate
vlastnost z Person
entity do Student
entity. Ujistěte se, že jste pro vlastnost také nastavili Nullable
na False
EnrollmentDate
.
Když teď entita Person
obsahuje pouze vlastnosti, které jsou společné Instructor
s entitami a Student
(kromě navigačních vlastností, které nepřesouváte), lze entitu použít pouze jako základní entitu ve struktuře dědičnosti. Proto je potřeba zajistit, aby se s ní nikdy nezacházelo jako s nezávislou entitou. Klikněte pravým tlačítkem na entitu Person
, vyberte Vlastnosti a potom v okně Vlastnosti změňte hodnotu vlastnosti Abstract na True.
Mapování entit instruktora a studenta na tabulku osob
Teď potřebujete Entity Frameworku říct, jak v databázi odlišit Instructor
entity a Student
.
Klikněte pravým tlačítkem na entitu Instructor
a vyberte Mapování tabulky. V okně Podrobnosti mapování klikněte na Přidat tabulku nebo Zobrazení a vyberte Osoba.
Klikněte na Přidat podmínku a pak vyberte HireDate.
Změňte operátor na Is a Value / Property na Not Null.
Opakujte postup pro entitu Students
a určete, že se tato entita mapuje na Person
tabulku, když EnrollmentDate
sloupec nemá hodnotu null. Pak datový model uložte a zavřete.
Sestavte projekt, abyste vytvořili nové entity jako třídy a zpřístupněte je v návrháři.
Použití entit instruktora a studenta
Při vytváření webových stránek, které pracují s daty studentů a instruktorů, jste data vysílali do Person
sady entit a vyfiltrovali HireDate
jste vlastnost nebo EnrollmentDate
, abyste vrácené údaje omezili na studenty nebo instruktory. Když teď ale vytvoříte vazbu mezi jednotlivými ovládacími prvky zdroje dat a Person
sadou entit, můžete určit, že se mají vybrat jenom Student
typy entit nebo Instructor
. Vzhledem k tomu, že Entity Framework ví, jak odlišit studenty a instruktory v Person
sadě entit, můžete odebrat Where
nastavení vlastnosti, které jste zadali ručně, abyste to udělali.
V Designer sady Visual Studio můžete zadat typ entity, který EntityDataSource
má ovládací prvek vybrat v rozevíracím seznamu Configure Data Source
EntityTypeFilter průvodce, jak je znázorněno v následujícím příkladu.
A v okně Vlastnosti můžete odebrat Where
hodnoty klauzule, které už nejsou potřeba, jak je znázorněno v následujícím příkladu.
Vzhledem k tomu, že jste změnili značky ovládacích EntityDataSource
prvků tak, aby používaly ContextTypeName
atribut, nemůžete spustit průvodce konfigurací zdroje dat u EntityDataSource
ovládacích prvků, které jste už vytvořili. Proto místo toho provedete požadované změny tak, že změníte značky.
Otevřete stránku Students.aspx . V ovládacím StudentsEntityDataSource
prvku odeberte Where
atribut a přidejte EntityTypeFilter="Student"
atribut. Kód teď bude vypadat podobně jako v následujícím příkladu:
<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>
Nastavením atributu EntityTypeFilter
zajistíte, že EntityDataSource
ovládací prvek vybere jenom zadaný typ entity. Pokud byste chtěli načíst typy entit i Student
Instructor
, nenastavili byste tento atribut. (Pomocí jednoho EntityDataSource
ovládacího prvku můžete načíst více typů entit jenom v případě, že tento ovládací prvek používáte pro přístup k datům jen pro čtení. Pokud k vkládání, aktualizaci nebo odstraňování entit používáte EntityDataSource
ovládací prvek a pokud sada entit, na kterou je vázána, může obsahovat více typů, můžete pracovat jenom s jedním typem entity a musíte nastavit tento atribut.)
Opakujte postup pro SearchEntityDataSource
ovládací prvek s výjimkou odebrání pouze části atributu Where
, která vybírá Student
entity místo odebrání vlastnosti úplně. Počáteční značka ovládacího prvku se teď bude podobat následujícímu příkladu:
<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 + '%'" >
Spusťte stránku a ověřte, že stále funguje stejně jako předtím.
Aktualizujte následující stránky, které jste vytvořili v předchozích kurzech, aby místo entit používaly nové Student
entity a a Instructor
Person
pak je spusťte a ověřte, že fungují stejně jako předtím:
V souboru StudentsAdd.aspx přidejte
EntityTypeFilter="Student"
doStudentsEntityDataSource
ovládacího prvku . Kód teď bude vypadat podobně jako v následujícím příkladu:<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server" ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" EntitySetName="People" EntityTypeFilter="Student" EnableInsert="True" </asp:EntityDataSource>
V about.aspx přidejte
EntityTypeFilter="Student"
doStudentStatisticsEntityDataSource
ovládacího prvku a odeberteWhere="it.EnrollmentDate is not null"
. Kód teď bude vypadat podobně jako v následujícím příkladu:<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>
V souborech Instructors.aspx a InstructorsCourses.aspx přidejte
EntityTypeFilter="Instructor"
doInstructorsEntityDataSource
ovládacího prvku a odeberteWhere="it.HireDate is not null"
. Kód v Instructors.aspx teď vypadá podobně jako v následujícím příkladu:<asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="false" EntitySetName="People" EntityTypeFilter="Instructor" Include="OfficeAssignment" EnableUpdate="True"> </asp:EntityDataSource>
Kód v InstructorsCourses.aspx se teď bude podobat následujícímu příkladu:
<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>
V důsledku těchto změn jste několika způsoby vylepšili udržovatelnost aplikace Contoso University. Přesunuli jste logiku výběru a ověřování mimo vrstvu uživatelského rozhraní (kód .aspx ) a udělali jste z ní nedílnou součást vrstvy přístupu k datům. To pomáhá izolovat kód aplikace od změn, které byste mohli v budoucnu provést ve schématu databáze nebo datovém modelu. Můžete se například rozhodnout, že studenti mohou být přijati jako pomůcky pro učitele, a proto by získali datum nástupu. Pak můžete přidat novou vlastnost, která odliší studenty od instruktorů, a aktualizovat datový model. Žádný kód ve webové aplikaci by se nemusel měnit s výjimkou případů, kdy jste chtěli zobrazit datum nástupu studentů. Další výhodou přidávání Instructor
entit a Student
je, že váš kód je srozumitelnější, než když odkazoval na Person
objekty, které byly ve skutečnosti studenty nebo instruktory.
Teď jste viděli jeden způsob, jak v Entity Frameworku implementovat vzor dědičnosti. V následujícím kurzu se naučíte používat uložené procedury, abyste měli větší kontrolu nad tím, jak Entity Framework přistupuje k databázi.