Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
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
Controllo EntityDataSource
Nell'esercitazione precedente è stato creato un sito Web, un database e un modello di dati. In questa esercitazione si lavora con il controllo fornito da ASP.NET per semplificare l'uso di un modello di dati di Entity Framework lavorando con EntityDataSource. Si creerà un GridView controllo per la visualizzazione e la modifica dei dati degli studenti, un DetailsView controllo per l'aggiunta di nuovi studenti e un DropDownList controllo per la selezione di un reparto (che verrà usato più avanti per visualizzare i corsi associati).
Si noti che in questa applicazione non si aggiungerà la convalida di input alle pagine che aggiornano il database e alcune delle operazioni di gestione degli errori non saranno affidabili come sarebbe necessario in un'applicazione di produzione. In questo modo l'esercitazione rimane focalizzata su Entity Framework, evitando che diventi troppo lunga. Per informazioni dettagliate su come aggiungere queste funzionalità all'applicazione, vedere Convalida dell'input dell'utente in pagine Web ASP.NET e gestione degli errori in pagine e applicazioni ASP.NET.
Aggiunta e configurazione del controllo EntityDataSource
Inizia configurando un EntityDataSource controllo per leggere le Person entità dal People set di entità.
Assicurarsi che Visual Studio sia aperto e che si stia lavorando con il progetto creato nella parte 1. Se il progetto non è stato compilato dopo aver creato il modello di dati o dopo l'ultima modifica apportata, compilare ora il progetto. Le modifiche apportate al modello di dati non vengono rese disponibili al progettista finché il progetto non viene compilato.
Creare una nuova pagina Web usando il modello Web Form usando il modello Pagina master e denominarla Students.aspx.
Specificare Site.Master come pagina master. Tutte le pagine create per queste esercitazioni useranno questa pagina master.
Nella visualizzazione Origine aggiungere un'intestazione h2 al Content controllo denominato Content2, come illustrato nell'esempio seguente:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Student List</h2>
</asp:Content>
Dalla scheda Dati della casella degli strumenti trascinare un EntityDataSource controllo nella pagina, rilasciarlo sotto l'intestazione e modificare l'ID in StudentsEntityDataSource:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Student List</h2>
<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server">
</asp:EntityDataSource>
</asp:Content>
Passare alla visualizzazione Struttura, cliccare sullo smart tag del controllo dell'origine dati e poi su Configura origine dati per avviare la procedura guidata Configura origine dati.
Nel passaggio della procedura guidata Configura ObjectContext, seleziona SchoolEntities come valore per connessione denominata e seleziona SchoolEntities come valore DefaultContainerName. Fare quindi clic su Avanti.
Nota: se si ottiene la finestra di dialogo seguente a questo punto, è necessario compilare il progetto prima di procedere.
Nel passaggio Configura selezione dati selezionare People come valore per EntitySetName. In Seleziona verificare che la casella di controllo Seleziona A sia selezionata. Selezionare quindi le opzioni per abilitare l'aggiornamento e l'eliminazione. Al termine, fare clic su Fine.
Configurazione delle regole di database per consentire l'eliminazione
Si creerà una pagina che consente agli utenti di eliminare gli studenti dalla Person tabella, che ha tre relazioni con altre tabelle (Course, StudentGradee OfficeAssignment). Per impostazione predefinita, il database impedirà di eliminare una riga in Person se sono presenti righe correlate in una delle altre tabelle. È possibile eliminare manualmente prima le righe correlate oppure configurare il database per eliminarle automaticamente quando si elimina una Person riga. Per i record degli studenti in questa esercitazione, configurerai il database per eliminare automaticamente i dati correlati. Poiché gli studenti possono avere righe correlate solo nella StudentGrade tabella, è necessario configurare solo una delle tre relazioni.
Se si usa il file di School.mdf scaricato dal progetto che include questa esercitazione, è possibile ignorare questa sezione perché queste modifiche alla configurazione sono già state apportate. Se il database è stato creato eseguendo uno script, configurare il database eseguendo le procedure seguenti.
In Esplora server aprire il diagramma di database creato nella parte 1. Fare clic con il pulsante destro del mouse sulla relazione tra Person e StudentGrade (la riga tra tabelle) e quindi scegliere Proprietà.
Nella finestra Proprietà, espandere INSERT e UPDATE Specification e impostare la proprietà DeleteRule a Cascade.
Salvare e chiudere il diagramma. Se viene chiesto se si vuole aggiornare il database, fare clic su Sì.
Per assicurarsi che il modello mantenga le entità in memoria sincronizzate con le operazioni eseguite dal database, è necessario impostare le regole corrispondenti nel modello di dati. Aprire SchoolModel.edmx, fare clic con il pulsante destro del mouse sulla linea di associazione tra Person e StudentGradee quindi scegliere Proprietà.
Nella finestra Proprietà impostare End1 OnDelete su Cascade.
Salvare e chiudere il file SchoolModel.edmx e quindi ricompilare il progetto.
In generale, quando il database cambia, sono disponibili diverse opzioni per la sincronizzazione del modello:
- Per determinati tipi di modifiche, ad esempio l'aggiunta o l'aggiornamento di tabelle, viste o stored procedure, fare clic con il pulsante destro del mouse nella finestra di progettazione e selezionare Aggiorna modello dal database per fare in modo che la finestra di progettazione modichi automaticamente le modifiche.
- Rigenerare il modello di dati.
- Apportare aggiornamenti manuali come questo.
In questo caso, è possibile rigenerare il modello o aggiornare le tabelle interessate dalla modifica della relazione, ma è necessario apportare di nuovo la modifica del nome del campo (da FirstName a FirstMidName).
Uso di un controllo GridView per leggere e aggiornare le entità
In questa sezione si userà un GridView controllo per visualizzare, aggiornare o eliminare studenti.
Aprire o passare a Students.aspx e passare alla visualizzazione Progettazione. Nella scheda Dati della casella degli strumenti trascinare un GridView controllo a destra del EntityDataSource controllo, denominarlo StudentsGridView, fare clic sullo smart tag e quindi selezionare StudentsEntityDataSource come origine dati.
Fare clic su Aggiorna schema (fare clic su Sì se viene richiesto di confermare), quindi fare clic su Abilita paging, Abilita ordinamento, Abilita modifica e Abilita eliminazione.
Fare clic su Modifica colonne.
Nella casella Campi selezionati eliminare PersonID, LastName e HireDate. In genere non viene visualizzata una chiave di record per gli utenti, la data di assunzione non è rilevante per gli studenti e si inseriscono entrambe le parti del nome in un campo, quindi è necessario solo uno dei campi del nome.
Selezionare il campo FirstMidName e quindi fare clic su Converti questo campo in un campo Modello.
Eseguire la stessa operazione per EnrollmentDate.
Fare clic su OK e quindi passare alla visualizzazione Origine . Le modifiche rimanenti saranno più facili da eseguire direttamente nel markup. Il markup del GridView controllo è ora simile all'esempio seguente.
<asp:GridView ID="StudentsGridView" runat="server" AllowPaging="True"
AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="PersonID"
DataSourceID="StudentsEntityDataSource">
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<asp:TemplateField HeaderText="FirstMidName" SortExpression="FirstMidName">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("FirstMidName") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("FirstMidName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="EnrollmentDate" SortExpression="EnrollmentDate">
<EditItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("EnrollmentDate") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("EnrollmentDate") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
La prima colonna dopo il campo del comando è un campo modello che visualizza attualmente il nome. Modificare il markup per questo campo modello in modo che sia simile all'esempio seguente:
<asp:TemplateField HeaderText="Name" SortExpression="LastName">
<EditItemTemplate>
<asp:TextBox ID="LastNameTextBox" runat="server" Text='<%# Bind("LastName") %>'></asp:TextBox>
<asp:TextBox ID="FirstNameTextBox" runat="server" Text='<%# Bind("FirstMidName") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>'></asp:Label>,
<asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstMidName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
In modalità di visualizzazione, due Label controlli visualizzano il nome e il cognome. In modalità di modifica vengono fornite due caselle di testo in modo da poter modificare il nome e il cognome. Come per i controlli Label in modalità di visualizzazione, si usano Bind ed espressioni Eval esattamente come si farebbe con i controlli origine dati di ASP.NET che si connettono direttamente ai database. L'unica differenza consiste nel fatto che si specificano proprietà di entità anziché colonne di database.
L'ultima colonna è un campo modello che visualizza la data di registrazione. Modificare il markup per questo campo in modo che sia simile all'esempio seguente:
<asp:TemplateField HeaderText="Enrollment Date" SortExpression="EnrollmentDate">
<EditItemTemplate>
<asp:TextBox ID="EnrollmentDateTextBox" runat="server" Text='<%# Bind("EnrollmentDate", "{0:d}") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="EnrollmentDateLabel" runat="server" Text='<%# Eval("EnrollmentDate", "{0:d}") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Sia in modalità di visualizzazione che di modifica, la stringa di formato "{0,d}" determina la visualizzazione della data nel formato "data breve". Il computer potrebbe essere configurato per visualizzare questo formato in modo diverso rispetto alle immagini visualizzate in questa esercitazione.
Si noti che in ognuno di questi campi modello, il progettista ha usato un'espressione Bind per impostazione predefinita, ma hai modificato in un'espressione Eval negli elementi ItemTemplate. L'espressione Bind rende i dati disponibili nelle GridView proprietà del controllo nel caso in cui sia necessario accedere ai dati nel codice. In questa pagina non è necessario accedere a questi dati nel codice, quindi è possibile usare Eval, che è più efficiente. Per altre informazioni, vedere Recupero dei dati dai controlli.
Revisione del markup del controllo EntityDataSource per migliorare le prestazioni
Nel markup per il controllo EntityDataSource, rimuovere gli attributi ConnectionString e DefaultContainerName e sostituirli con l'attributo ContextTypeName="ContosoUniversity.DAL.SchoolEntities". Si tratta di una modifica che è necessario apportare ogni volta che si crea un EntityDataSource controllo, a meno che non sia necessario usare una connessione diversa da quella hardcoded nella classe del contesto dell'oggetto. L'uso dell'attributo ContextTypeName offre i vantaggi seguenti:
- Prestazioni migliori. Quando il
EntityDataSourcecontrollo inizializza il modello di dati usando gliConnectionStringattributi eDefaultContainerName, esegue operazioni aggiuntive per caricare i metadati in ogni richiesta. Questo non è necessario se si specifica l'attributoContextTypeName. - Il caricamento differito è abilitato per impostazione predefinita nelle classi di contesto oggetto generate (ad esempio
SchoolEntitiesin questo tutorial) in Entity Framework 4.0. Ciò significa che le proprietà di navigazione vengono caricate automaticamente con i dati correlati quando necessario. Il caricamento differito è illustrato in modo più dettagliato più avanti in questo tutorial. - Tutte le personalizzazioni applicate alla classe di contesto dell'oggetto (in questo caso, la
SchoolEntitiesclasse ) saranno disponibili per i controlli che usano ilEntityDataSourcecontrollo . La personalizzazione della classe di contesto dell'oggetto è un argomento avanzato non trattato in questa serie di esercitazioni. Per altre informazioni, vedere Estensione dei tipi generati da Entity Framework.
Il markup sarà ora simile all'esempio seguente (l'ordine delle proprietà potrebbe essere diverso):
<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="People"
EnableDelete="True" EnableUpdate="True">
</asp:EntityDataSource>
L'attributo EnableFlattening fa riferimento a una funzionalità necessaria nelle versioni precedenti di Entity Framework perché le colonne chiave esterna non sono state esposte come proprietà dell'entità. La versione corrente consente di usare associazioni di chiavi esterne, il che significa che le proprietà della chiave esterna vengono esposte per tutte le associazioni tranne quelle molti-a-molti. Se le entità hanno proprietà di chiave esterna e nessun tipo complesso, è possibile lasciare questo attributo impostato su False. Non rimuovere l'attributo dal markup, perché il valore predefinito è True. Per altre informazioni, vedere Flattening Objects (EntityDataSource).
Eseguire la pagina e visualizzare un elenco di studenti e dipendenti (verranno filtrati solo gli studenti nell'esercitazione successiva). Il nome e il cognome vengono visualizzati insieme.
Per ordinare la visualizzazione, fare clic sul nome di una colonna.
Fare clic su Modifica in qualsiasi riga. Le caselle di testo vengono visualizzate in cui è possibile modificare il nome e il cognome.
Il pulsante Elimina funziona anche. Fare clic su Elimina per una riga con una data di registrazione e la riga scompare. Le righe senza una data di iscrizione rappresentano i docenti e potresti riscontrare un errore di integrità referenziale. Nel prossimo tutorial, filtrerai l'elenco in modo da includere solo gli studenti.
Visualizzazione di dati da una proprietà di navigazione
Si supponga ora di voler conoscere il numero di corsi a cui ogni studente è iscritto. Entity Framework fornisce tali informazioni nella StudentGrades proprietà di navigazione dell'entità Person . Poiché la progettazione del database non consente a uno studente di essere iscritto a un corso senza avere un voto assegnato, per questa esercitazione è possibile presupporre che la presenza di una riga nella riga della StudentGrade tabella associata a un corso sia uguale a quella di essere iscritti al corso. La Courses proprietà di navigazione è solo per gli istruttori.
Quando si usa l'attributo ContextTypeName del EntityDataSource controllo, Entity Framework recupera automaticamente le informazioni per una proprietà di navigazione quando si accede a tale proprietà. Questa operazione è denominata caricamento ritardato. Tuttavia, ciò può risultare inefficiente, perché comporta una chiamata separata al database ogni volta che sono necessarie informazioni aggiuntive. Se sono necessari dati della proprietà di navigazione per ogni entità restituita dal EntityDataSource controllo, è più efficiente recuperare i dati correlati insieme all'entità stessa in una singola chiamata al database. Questo metodo viene chiamato caricamento anticipato e si specifica il caricamento anticipato per una proprietà di navigazione impostando il valore della proprietà di controllo EntityDataSource.
In Students.aspx, vuoi mostrare il numero di corsi per ogni studente, quindi il caricamento ansioso è la scelta migliore. Se si visualizzavano tutti gli studenti ma si mostra il numero di corsi solo per alcuni di essi (che richiederebbe la scrittura di codice oltre al markup), il caricamento differito potrebbe essere una scelta migliore.
Aprire o passare a Students.aspx, passare alla visualizzazione Progettazione , selezionare StudentsEntityDataSourcee nella finestra Proprietà impostare la proprietà Includi su StudentGrades. Se si desidera ottenere più proprietà di navigazione, è possibile specificare i relativi nomi separati da virgole, ad esempio StudentGrades, Courses.
Passare alla visualizzazione Origine . Nel controllo StudentsGridView, dopo l'ultimo elemento asp:TemplateField, aggiungere il seguente nuovo campo modello:
<asp:TemplateField HeaderText="Number of Courses">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("StudentGrades.Count") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Nell'espressione Eval è possibile fare riferimento alla proprietà di navigazione StudentGrades. Poiché questa proprietà contiene una raccolta, dispone di una Count proprietà che è possibile utilizzare per visualizzare il numero di corsi in cui viene registrato lo studente. In un'esercitazione successiva si vedrà come visualizzare i dati dalle proprietà di navigazione che contengono singole entità anziché raccolte. Si noti che non è possibile utilizzare BoundField elementi per visualizzare i dati dalle proprietà di navigazione.
Eseguire la pagina e viene ora visualizzato il numero di corsi a cui ogni studente è iscritto.
Uso di un controllo DetailsView per inserire entità
Il passaggio successivo consiste nel creare una pagina con un DetailsView controllo che consentirà di aggiungere nuovi studenti. Chiudere il browser e quindi creare una nuova pagina Web usando la pagina master Site.Master . Assegnare alla pagina il nome StudentsAdd.aspx e quindi passare alla visualizzazione Origine .
Aggiungere il markup seguente per sostituire il markup esistente per il Content controllo denominato Content2:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Add New Students</h2>
<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EnableInsert="True" EntitySetName="People">
</asp:EntityDataSource>
<asp:DetailsView ID="StudentsDetailsView" runat="server"
DataSourceID="StudentsEntityDataSource" AutoGenerateRows="False"
DefaultMode="Insert">
<Fields>
<asp:BoundField DataField="FirstMidName" HeaderText="First Name"
SortExpression="FirstMidName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name"
SortExpression="LastName" />
<asp:BoundField DataField="EnrollmentDate" HeaderText="Enrollment Date"
SortExpression="EnrollmentDate" />
<asp:CommandField ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
</asp:Content>
Questo markup crea un EntityDataSource controllo simile a quello creato in Students.aspx, con la differenza che abilita l'inserimento. Come per il GridView controllo, i campi associati del DetailsView controllo vengono codificati esattamente come per un controllo dati che si connette direttamente a un database, ad eccezione del fatto che fanno riferimento alle proprietà dell'entità. In questo caso, il controllo viene usato solo per l'inserimento DetailsView di righe, quindi è stata impostata la modalità predefinita su Insert.
Avviare la pagina e aggiungere un nuovo studente.
Non succederà nulla dopo l'inserimento di un nuovo studente, ma se si esegue ora Students.aspx, verranno visualizzate le nuove informazioni sugli studenti.
Visualizzazione dei dati in un elenco a tendina
Nei passaggi seguenti assocerai un controllo DropDownList a un set di entità utilizzando un controllo EntityDataSource. In questa parte della guida, non farai molto con questo elenco. Nelle parti successive, tuttavia, si userà l'elenco per consentire agli utenti di selezionare un reparto per visualizzare i corsi associati al reparto.
Creare una nuova pagina Web denominata Courses.aspx. Nella visualizzazione Origine aggiungere un'intestazione al Content controllo denominato Content2:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Courses by Department</h2>
</asp:Content>
Nella visualizzazione Progettazione aggiungere un EntityDataSource controllo alla pagina come in precedenza, ad eccezione di questa volta denominarlo DepartmentsEntityDataSource. Selezionare Reparti come valore EntitySetName e selezionare solo le proprietà DepartmentID e Name .
Nella scheda Standard della casella degli strumenti trascinare un DropDownList controllo nella pagina, denominarlo DepartmentsDropDownList, fare clic sullo smart tag e selezionare Scegli origine dati per avviare la Configurazione guidata origine dati.
Nel passaggio Scegliere un'origine dati selezionare DepartmentsEntityDataSource come origine dati, fare clic su Aggiorna schema e quindi selezionare Nome come campo dati per visualizzare e DepartmentID come campo dati valore. Fare clic su OK.
Il metodo utilizzato per associare il controllo tramite Entity Framework è lo stesso degli altri controlli origine dati ASP.NET, con la differenza che specificate le entità e le proprietà dell'entità.
Passare alla visualizzazione Origine e aggiungere "Selezionare un reparto:" immediatamente prima del DropDownList comando.
Select a department:
<asp:DropDownList ID="DropDownList1" runat="server"
DataSourceID="EntityDataSource1" DataTextField="Name"
DataValueField="DepartmentID">
</asp:DropDownList>
Come promemoria, a questo punto modifica il markup del controllo EntityDataSource sostituendo gli attributi ConnectionString e DefaultContainerName con l'attributo ContextTypeName="ContosoUniversity.DAL.SchoolEntities". È spesso consigliabile attendere fino a quando non è stato creato il controllo associato ai dati collegato al controllo dell'origine dati prima di modificare il markup del controllo EntityDataSource, perché dopo aver apportato la modifica, il progettista non fornirà un'opzione Aggiorna schema nel controllo associato ai dati.
Esegui la pagina e puoi selezionare un dipartimento dall'elenco a discesa.
In questo modo viene completata l'introduzione all'uso del EntityDataSource controllo . L'uso di questo controllo in genere non è diverso dall'uso di altri controlli origine dati ASP.NET, ad eccezione del fatto che si fa riferimento a entità e proprietà anziché a tabelle e colonne. L'unica eccezione è quando si desidera accedere alle proprietà di navigazione. Nell'esercitazione successiva si noterà che la sintassi usata con il controllo EntityDataSource potrebbe differire anche quando si filtrano, raggruppano e ordinano i dati, da altri controlli di origine dati.