Sdílet prostřednictvím


Začínáme se službou Entity Framework 4.0 Database First a ASP.NET 4 Web Forms – část 6

Tom Dykstra

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).

image11

Entity Framework můžete nakonfigurovat tak, aby vytvářel InstructorStudent 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 .

obrázek12

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 a Student typy entit, které jsou odvozeny z Person.
  • 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, zda Person řá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.

obrázek01

V dialogovém okně Přidat entitu pojmenujte entitu Instructor a nastavte její možnost Základní typ na Person.

obrázek02

Klikněte na OK. Návrhář vytvoří entitu Instructor , která je odvozena z Person entity. Nová entita ještě nemá žádné vlastnosti.

obrázek03

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.

obrázek04

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.

obrázek05

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 FalseEnrollmentDate .

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.

obrázek06

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.

obrázek07

Klikněte na Přidat podmínku a pak vyberte HireDate.

obrázek09

Změňte operátor na Is a Value / Property na Not Null.

obrázek10

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 SourceEntityTypeFilter průvodce, jak je znázorněno v následujícím příkladu.

image13

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.

image14

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 StudentInstructor , 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.

image15

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 InstructorPerson pak je spusťte a ověřte, že fungují stejně jako předtím:

  • V souboru StudentsAdd.aspx přidejte EntityTypeFilter="Student" do StudentsEntityDataSource 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>
    

    obrázek16

  • V about.aspx přidejte EntityTypeFilter="Student" do StudentStatisticsEntityDataSource ovládacího prvku a odeberte Where="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>
    

    image17

  • V souborech Instructors.aspx a InstructorsCourses.aspx přidejte EntityTypeFilter="Instructor" do InstructorsEntityDataSource ovládacího prvku a odeberte Where="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>
    

    image18

    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>
    

    image19

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.