Condividi tramite


Introduzione a Entity Framework 4.0 Database First e ASP.NET 4 Web Form - Parte 6

di Tom Dykstra

L'applicazione Web di esempio Contoso University illustra come creare ASP.NET applicazioni Web Form usando Entity Framework 4.0 e Visual Studio 2010. Per informazioni sulla serie di esercitazioni, vedere la prima esercitazione della serie

Implementazione dell'ereditarietà di tabelle per gerarchia

Nell'esercitazione precedente sono stati usati dati correlati aggiungendo ed eliminando relazioni e aggiungendo una nuova entità con una relazione con un'entità esistente. Questa esercitazione illustra come implementare l'ereditarietà nel modello di dati.

Nella programmazione orientata agli oggetti è possibile usare l'ereditarietà per semplificare l'uso delle classi correlate. Ad esempio, è possibile creare Instructor classi e Student che derivano da una Person classe di base. È possibile creare gli stessi tipi di strutture di ereditarietà tra le entità in Entity Framework.

In questa parte dell'esercitazione non verranno create nuove pagine Web. Si aggiungeranno invece entità derivate al modello di dati e si modificheranno le pagine esistenti per usare le nuove entità.

Ereditarietà tabella per gerarchia e tabella per tipo

Un database può archiviare informazioni sugli oggetti correlati in una tabella o in più tabelle. Nel database, ad esempio, School la Person tabella include informazioni su studenti e insegnanti in una singola tabella. Alcune colonne si applicano solo agli insegnanti (HireDate), alcuni solo agli studenti (EnrollmentDate) e alcuni a entrambi (LastName, FirstName).

image11

È possibile configurare Entity Framework per creare InstructorStudent entità che ereditano dall'entità Person . Questo modello di generazione di una struttura di ereditarietà di entità da una singola tabella di database è detta ereditarietà della tabella per gerarchia (TPH).

Per i corsi, il School database usa un modello diverso. I corsi online e i corsi in loco sono archiviati in tabelle separate, ognuna delle quali ha una chiave esterna che punta alla Course tabella. Le informazioni comuni a entrambi i tipi di corso vengono archiviate solo nella Course tabella.

image12

È possibile configurare il modello di dati di Entity Framework in modo che OnlineCourse e OnsiteCourse le entità ereditino dall'entità Course . Questo modello di generazione di una struttura di ereditarietà di entità da tabelle separate per ogni tipo, con ogni tabella separata che fa riferimento a una tabella che archivia i dati comuni a tutti i tipi, viene chiamata ereditarietà della tabella per tipo (TPT).

I modelli di ereditarietà TPH offrono in genere prestazioni migliori in Entity Framework rispetto ai modelli di ereditarietà TPT, perché i modelli TPT possono generare query di join complesse. Questa procedura dettagliata illustra come implementare l'ereditarietà TPH. A tale scopo, seguire questa procedura:

  • Creare i tipi di entità Instructor e Student che derivano da Person.
  • Spostare le proprietà che appartengono alle entità derivate dall'entità Person alle entità derivate.
  • Impostare vincoli sulle proprietà nei tipi derivati.
  • Rendere l'entità un'entità Person astratta.
  • Eseguire il mapping di ogni entità derivata alla Person tabella con una condizione che specifica come determinare se una Person riga rappresenta il tipo derivato.

Aggiunta di entità insegnante e studente

Aprire il file SchoolModel.edmx , fare clic con il pulsante destro del mouse su un'area non occupato nella finestra di progettazione, selezionare Aggiungi e quindi selezionare Entità.

image01

Nella finestra di dialogo Aggiungi entità assegnare all'entità Instructor il nome e impostare l'opzione Tipo di base su Person.

image02

Fare clic su OK. Il progettista crea un'entità Instructor che deriva dall'entità Person. La nuova entità non dispone ancora di proprietà.

image03

Ripetere la procedura per creare un'entità Student che deriva anche da Person.

Solo gli istruttori hanno date di assunzione, quindi è necessario spostare tale proprietà dall'entità Person all'entità Instructor . Nell'entità Person fare clic con il pulsante destro del mouse sulla HireDate proprietà e scegliere Taglia. Fare quindi clic con il pulsante destro del mouse su Proprietà nell'entità Instructor e scegliere Incolla.

image04

La data di assunzione di un'entità Instructor non può essere nulla. Fare clic con il pulsante destro del mouse sulla proprietà , scegliere Proprietà, quindi nella finestra Proprietà, modificare in .

image05

Ripetere la procedura per spostare la proprietà EnrollmentDate dall'entità Person all'entità Student. Assicurarsi di impostare anche Nullable su False per la proprietà EnrollmentDate.

Ora che un'entità Person ha solo le proprietà comuni a Instructor e Student le entità (a parte le proprietà di navigazione, che non si spostano), l'entità può essere usata solo come entità di base nella struttura di ereditarietà. È quindi necessario assicurarsi che non venga mai considerato come un'entità indipendente. Fare clic con il pulsante destro del mouse sull'entità Person , selezionare Proprietà e quindi nella finestra Proprietà modificare il valore della proprietà Abstract su True.

image06

Mapping delle entità Docente e Studente alla tabella Person

È ora necessario indicare a Entity Framework come distinguere tra Instructor le entità e Student nel database.

Fare clic con il pulsante destro del mouse sull'entità Instructor e scegliere Mappatura tabella. Nella finestra Dettagli mappatura fare clic su Aggiungi Tabella o Vista e selezionare Persona.

image07

Fare clic su Aggiungi una condizione e quindi selezionare HireDate.

image09

Cambiare Operatore in Is e Valore / Proprietà in Not Null.

image10

Ripetere la procedura per l'entità Students, specificando che questa entità mappa alla tabella Person quando la colonna EnrollmentDate non è nulla. Salvare e chiudere quindi il modello di dati.

Compilare il progetto per creare le nuove entità come classi e renderle disponibili nella finestra di progettazione.

Uso delle entità Instructor e Student

Quando hai creato le pagine Web che funzionano con i dati di studenti e insegnanti, li hai associati al set di entità Person e li hai filtrati sulla proprietà HireDate o EnrollmentDate per limitare i dati restituiti a studenti o insegnanti. Tuttavia, ora quando si associa ogni controllo origine dati al Person set di entità, è possibile specificare che devono essere selezionati solo Student o Instructor tipi di entità. Poiché Entity Framework sa come distinguere gli studenti e gli insegnanti nel Person set di entità, è possibile rimuovere le impostazioni delle Where proprietà immesse manualmente per farlo.

Nel Designer di Visual Studio, è possibile specificare il tipo di entità che un EntityDataSource controllo deve selezionare nel menu a tendina EntityTypeFilter della procedura guidata Configure Data Source, come illustrato nell'esempio seguente.

image13

Nella finestra Proprietà è possibile rimuovere Where i valori della clausola non più necessari, come illustrato nell'esempio seguente.

image14

Tuttavia, poiché hai modificato il markup per utilizzare l'attributo ContextTypeName sui controlli EntityDataSource, non è possibile eseguire la procedura guidata Configura origine dati sui controlli EntityDataSource già creati. Di conseguenza, le modifiche necessarie verranno apportate modificando il markup.

Aprire la pagina Students.aspx . StudentsEntityDataSource Nel controllo rimuovere l'attributo Where e aggiungere un EntityTypeFilter="Student" attributo. Il markup apparirà ora come il seguente esempio.

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

L'impostazione dell'attributo EntityTypeFilter garantisce che il EntityDataSource controllo selezioni solo il tipo di entità specificato. Se si volessero recuperare entrambi i tipi di entità Student e Instructor, non si dovrebbe impostare questo attributo. È possibile recuperare più tipi di entità con un EntityDataSource solo controllo solo se si usa il controllo per l'accesso ai dati di sola lettura. Se si usa un EntityDataSource controllo per inserire, aggiornare o eliminare entità e se il set di entità a cui è associato può contenere più tipi, è possibile usare solo un tipo di entità e impostare questo attributo.

Ripetere la procedura per il SearchEntityDataSource controllo, ad eccezione di rimuovere solo la parte dell'attributo Where che seleziona le Student entità invece di rimuovere completamente la proprietà. Il tag di apertura del controllo sarà ora simile all'esempio seguente:

<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 + '%'" >

Eseguire la pagina per verificare che funzioni ancora come in precedenza.

image15

Aggiornare le seguenti pagine create nelle esercitazioni precedenti in modo che usino le nuove entità Student e Instructor anziché le entità Person, quindi eseguirle per verificare che funzionino come in precedenza.

  • In StudentsAdd.aspx aggiungere EntityTypeFilter="Student" al StudentsEntityDataSource controllo . Il markup sarà ora simile all'esempio seguente:

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

    image16

  • In About.aspx aggiungere EntityTypeFilter="Student" al StudentStatisticsEntityDataSource controllo e rimuovere Where="it.EnrollmentDate is not null". Ora il markup somiglierà al seguente esempio:

    <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

  • In Instructors.aspx e InstructorsCourses.aspx aggiungere EntityTypeFilter="Instructor" al InstructorsEntityDataSource controllo e rimuovere Where="it.HireDate is not null". Il markup in Instructors.aspx ora è simile all'esempio seguente:

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

    image18

    Il markup in InstructorsCourses.aspx sarà ora simile all'esempio seguente:

    <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

In seguito a queste modifiche, è stata migliorata la manutenibilità dell'applicazione Contoso University in diversi modi. La logica di selezione e convalida è stata spostata dal livello dell'interfaccia utente (.aspx markup) ed è stata resa parte integrante del livello di accesso ai dati. Ciò consente di isolare il codice dell'applicazione dalle modifiche che potrebbero essere apportate in futuro allo schema del database o al modello di dati. Ad esempio, si potrebbe decidere che gli studenti potrebbero essere assunti come aiuti degli insegnanti e quindi ottenere una data di assunzione. È quindi possibile aggiungere una nuova proprietà per distinguere gli studenti dagli insegnanti e aggiornare il modello di dati. Nessun codice nell'applicazione Web deve cambiare tranne dove si desidera visualizzare una data di assunzione per gli studenti. Un altro vantaggio dell'aggiunta di entità Instructor e Student è che il vostro codice è più facilmente comprensibile rispetto a quando si fa riferimento a Person oggetti che erano in realtà studenti o insegnanti.

È stato illustrato un modo per implementare un modello di ereditarietà in Entity Framework. Nell'esercitazione seguente si apprenderà come usare le stored procedure per avere un maggiore controllo sul modo in cui Entity Framework accede al database.