Procedura dettagliata: eseguire il mapping dell'ereditarietà tabella per gerarchia (strumenti di Entity Data Model)
In questo argomento viene illustrato come implementare l'ereditarietà tabella per gerarchia modificando il modello concettuale definito in un file con estensione edmx. L'ereditarietà tabella per gerarchia utilizza una tabella di database per gestire i dati relativi a tutti i tipi di entità in una gerarchia di ereditarietà.
In questa procedura dettagliata verrà implementata l'ereditarietà tabella per gerarchia modificando il modello concettuale utilizzato nell'applicazione CourseManager. Per ulteriori informazioni, vedere la sezione Prerequisiti più avanti in questo argomento.
Nel modello concettuale dell'applicazione CourseManager il tipo di entità Person dispone di due proprietà, HireDate e EnrollmentDate, che possono appartenere ai nuovi tipi di entità (Instructor e Student rispettivamente) che ereditano da Person. L'implementazione dell'ereditarietà tabella per gerarchia di questo caso specifico viene riepilogata nei passaggi seguenti. Le procedure dettagliate includono una descrizione più particolareggiata.
Creare due nuovi tipi di entità, Instructor e Student.
Impostare il tipo di base per ogni nuovo tipo di identità su Person.
Spostare la proprietà HireDate da Person a Instructor e la proprietà EnrollmentDate da Person a Student.
Convertire il tipo di entità Person in un tipo astratto.
Eseguire il mapping del tipo di entità Instructor alla tabella Person con due condizioni: HireDate Is Not Null e EnrollmentDate Is Null.
Eseguire il mapping del tipo di entità Student alla tabella Person con due condizioni: EnrollmentDate Is Not Null e HireDate Is Null.
Prerequisiti
Per completare questa procedura dettagliata è necessario compilare l'applicazione CourseManager. Per ulteriori informazioni e istruzioni, vedere la Guida rapida di Entity Framework. Dopo avere compilato questa applicazione, si procede all'implementazione dell'ereditarietà tabella per gerarchia attraverso la modifica dei mapping e del modello concettuale. La funzionalità dell'applicazione viene quindi estesa per visualizzare l'iscrizione a un corso selezionato.
Nota: |
---|
Dal momento che in molti argomenti contenenti procedure dettagliate di questa documentazione viene utilizzata l'applicazione CourseManager come punto di partenza, è consigliabile utilizzare una copia di tale applicazione anziché modificarne il codice originale. |
In questa procedura dettagliata si presuppone che il lettore disponga di una competenza di base di Visual Studio, .NET Framework e della programmazione in Visual C# o Visual Basic.
Implementazione dell'ereditarietà tabella per gerarchia
In questa procedura verrà modificato il modello SchoolModel per implementare l'ereditarietà tabella per gerarchia. Per una presentazione video della seguente procedura, vedere .
Per implementare l'ereditarietà tabella per gerarchia
Aprire la soluzione CourseManager in Visual Studio.
In Esplora soluzioni fare doppio clic sul file School.edmx.
Il file School.edmx verrà aperto in ADO.NET Entity Data Model Designer (Entity Designer).
Fare clic con il pulsante destro del mouse in un spazio vuoto dell'area di progettazione di Entity Designer, scegliere Aggiungi, quindi fare clic su Entità.
Verrà visualizzata la finestra di dialogo Nuova Entity.
Digitare Instructor per Nome entità e selezionare Person dall'elenco a discesa per il Tipo di base.
Scegliere OK.
Nell'area di progettazione verrà creato e visualizzato un nuovo tipo di entità.
Ripetere i passaggi da 3 a 5, ma digitare Student per Nome entità nel secondo passaggio.
Sono ora disponibili due nuovi tipi di entità, Instructor e Student, visualizzati nell'area di progettazione. Le frecce puntano dai nuovi tipi di entità al tipo di entità Person. Questo indica che Person è il tipo di base per i nuovi tipi di entità.
Fare clic con il pulsante destro del mouse sulla proprietà HireDate (in Proprietà scalari) del tipo di entità Person. Scegliere Taglia.
Fare clic con il pulsante destro del mouse su Proprietà scalari del tipo di entità Instructor e scegliere Incolla.
Fare clic con il pulsante destro del mouse sulla proprietà HireDate e scegliere Proprietà.
Nella finestra Proprietà impostare la proprietà Nullable su false.
Ripetere i passaggi da 7 a 10, ma tagliare la proprietà EnrollmentDate del tipo di entità Person e incollarla nel tipo di entità Student.
Selezionare il tipo di entità Person. Nella finestra Proprietà impostare la proprietà Abstract su true.
Non è necessario utilizzare i tipi astratti per modellare gli scenari tabella per gerarchia in generale. In questo esempio vengono utilizzati tipi astratti per illustrarne l'utilizzo in un modello concettuale.
Nota: Gli altri passaggi di questa procedura presuppongono che la finestra Dettagli Mapping sia aperta.Se la finestra non è visibile, fare clic con il pulsante destro del mouse sull'area di progettazione e scegliere Dettagli Mapping. Selezionare il tipo di entità Instructor e fare clic su <Aggiungi tabella o visualizzazione> nella finestra Dettagli Mapping.
Il campo <Aggiungi tabella o visualizzazione> diventa un elenco a discesa di tabelle o visualizzazioni a cui è possibile eseguire il mapping dell'entità selezionata.
Selezionare Person dall'elenco a discesa.
La finestra Dettagli Mapping viene aggiornata con i mapping di colonne predefiniti e con un'opzione per l'aggiunta di una condizione.
Fare clic su <Aggiungere una Condition>.
Il campo <Aggiungere una Condition> diventa un elenco a discesa di colonne in cui è possibile impostare le condizioni.
Selezionare HireDate dall'elenco a discesa.
Viene visualizzato un altro campo <Aggiungere una Condition>.
Nella colonna Operatore della finestra Dettagli Mapping selezionare Is dall'elenco a discesa.
Nella colonna Proprietà/Valore selezionare Not Null.
Fare clic su <Aggiungere una Condition>.
Selezionare EnrollmentDate nell'elenco a discesa.
Nella colonna Operatore selezionare Is nell'elenco a discesa.
Nella colonna Proprietà/Valore selezionare Null.
Nota: Se un valore specificato in Proprietà/Valore è utilizzato in una condizione, non può essere anche una proprietà di entità, a meno che nella condizione non venga utilizzato un operatore di confronto Is Null o Is Not Null. Ripetere i passaggi da 13 a 22 per il tipo di entità Student, ma creare le condizioni HireDate Is Null e EnrollmentDate Is Not Null.
L'ereditarietà della tabella per gerarchia è ora implementata.
Creazione di un'associazione tra Instructor e OfficeAssignment
In questa sezione si modificherà l'associazione tra Person e OfficeAssignment in modo che sia tra Instructor e OfficeAssignment. La modifica dell'associazione in questo modo è coerente con lo scopo del modello.
Per creare un'associazione tra Instructor e OfficeAssignment
Fare clic con il pulsante destro del mouse sull'associazione tra Person e OfficeAssignment e selezionare Elimina.
Fare clic con il pulsante destro del mouse in un spazio vuoto dell'area di progettazione di Entity Designer, scegliere Aggiungi, quindi selezionare Associazione.
Per una Estremità dell'associazione, selezionare Instructor dall'elenco a discesa Entità e selezionare 1 (Uno) dall'elenco a discesa Molteplicità.
Per l'altra Estremità dell'associazione, selezionare OfficeAssignment dall'elenco a discesa Entità e selezionare 0..1 (Zero o uno) dall'elenco a discesa Molteplicità.
Scegliere OK.
Fare clic con il pulsante destro del mouse sulla nuova associazione Instructor e OfficeAssignment e selezionare Proprietà.
Nella finestra Proprietà, selezionare Vincolo referenziale, quindi fare clic sul pulsante con i puntini di sospensione (...) visualizzato nella colonna dei valori.
Verrà visualizzata la finestra di dialogo Vincolo referenziale.
Selezionare Instructor dall'elenco a discesa Principale.
Scegliere OK.
È stata aggiunta un'associazione tra Instructor e OfficeAssignment.
Costruzione dell'interfaccia utente
A questo punto verrà aggiunto un pulsante al form CourseViewer che carica e visualizza il form Enrollment. Dopodiché, verranno aggiunti due controlli ComboBox e un controllo ListBox al form Enrollment. Il primo controllo ComboBox consente di selezionare un reparto. Il secondo controllo ComboBox consente di selezionare un corso in base al reparto selezionato nel primo ComboBox. Nel controllo ListBox viene visualizzato un elenco di studenti e docenti per il corso selezionato.
Per costruire l'interfaccia utente
Fare clic con il pulsante destro del mouse sul progetto CourseManager in Esplora soluzioni, scegliere Aggiungi, quindi selezionare Nuovo elemento.
Verrà visualizzata la finestra di dialogo Aggiungi nuovo elemento.
Selezionare Windows Form, impostare il nome del form su Enrollment.vb o Enrollment.cs, a seconda del linguaggio utilizzato, e fare clic su Aggiungi.
Un nuovo form verrà aggiunto al progetto e aperto nella finestra di progettazione dei form. Il nome del form viene impostato su Enrollment, mentre il testo viene impostato su Enrollment.
Trascinare un controllo ComboBox dalla casella degli strumenti nel form e impostarne il nome su departmentList nella finestra Proprietà.
Trascinare un altro controllo ComboBox nel form e impostarne il nome su courseList.
Trascinare un controllo Listbox dalla casella degli strumenti nel form. Impostarne il nome su studentList nella finestra Proprietà.
In Esplora soluzioni fare doppio clic su CourseViewer.cs o su CourseViewer.vb.
Verrà aperta la visualizzazione Progettazione del form CourseViewer.
Trascinare un controllo Button dalla casella degli strumenti nel form CourseViewer.
Nella finestra Proprietà impostare il nome del pulsante su viewEnrollment e impostare il testo del pulsante su View Enrollment.
Fare doppio clic sul pulsante viewEnrollment.
Verrà visualizzato il file code-behind per il form CourseViewer.
Aggiungere il codice seguente al gestore eventi viewEnrollment_click:
Dim enrollmentForm As New Enrollment() enrollmentForm.Visible = True
Enrollment enrollmentForm = new Enrollment(); enrollmentForm.Visible = true;
L'interfaccia utente è ora completa.
Esecuzione di query sul modello concettuale
In questa procedura verrà eseguita una query sul modello concettuale e verranno associati i risultati ai controlli Windows Form. Per ulteriori informazioni sull'associazione di oggetti ai controlli, vedere Binding Objects to Controls (Entity Framework).
Per eseguire query sul modello concettuale
Fare doppio clic sul form Enrollment dopo averlo aperto nella finestra di progettazione dei form.
Verrà visualizzato il file code-behind per il form Enrollment.
Aggiungere le seguenti istruzioni using (C#) o Imports (Visual Basic).
Imports System.Data.Objects Imports System.Data.Objects.DataClasses
using System.Data.Objects; using System.Data.Objects.DataClasses;
Aggiungere una proprietà alla classe Enrollment che rappresenta il contesto dei dati:
' Create an ObjectContext instance based on SchoolEntity. Private schoolContext As SchoolEntities
// Create an ObjectContext instance based on SchoolEntities. private SchoolEntities schoolContext;
Nel gestore eventi Enrollment_Load aggiungere codice per inizializzare il contesto dell'oggetto e associare il controllo ComboBox a una query che restituisce informazioni su tutti i reparti e i corsi correlati.
' Initialize the ObjectContext. schoolContext = New SchoolEntities() ' Define a query that returns all Department objects and ' related Course objects, ordered by name. Dim departmentQuery As ObjectQuery(Of Department) = _ schoolContext.Departments.Include("Courses") _ .OrderBy("it.Name") ' Bind the ComboBox control to the query, which is ' executed during data binding. Me.departmentList.DataSource = departmentQuery _ .Execute(MergeOption.OverwriteChanges) Me.departmentList.DisplayMember = "Name"
// Initialize the ObjectContext. schoolContext = new SchoolEntities(); // Define a query that returns all Department objects // and related Course objects, ordered by name. ObjectQuery<Department> departmentQuery = schoolContext.Departments.Include("Courses") .OrderBy("it.Name"); // Bind the ComboBox control to the query. this.departmentList.DataSource = departmentQuery .Execute(MergeOption.OverwriteChanges); this.departmentList.DisplayMember = "Name";
Tornare alla visualizzazione Progettazione del form Enrollment e fare doppio clic sul controllo departmentList ComboBox.
Il gestore eventi departmentList_SelectedIndexChanged viene creato nel file code-behind.
Aggiungere codice al gestore eventi per associare il controllo courseList ComboBox alle proprietà Course dell'oggetto Department selezionato.
' Get the object for the selected department Dim department As Department = CType(Me.departmentList _ .SelectedItem, Department) ' Bind the ComboBox control Course properties of ' the selected Department. courseList.DataSource = department.Courses courseList.DisplayMember = "Title"
// Get the object for the selected department. Department department = (Department)this.departmentList.SelectedItem; // Bind the ComboBox control to the Course // properties of the selected Department. courseList.DataSource = department.Courses; courseList.DisplayMember = "Title";
Tornare alla visualizzazione Progettazione del form Enrollment e fare doppio clic sul controllo courseList ComboBox.
Il gestore eventi courseList_SelectedIndexChanged viene creato nel file code-behind.
Aggiungere codice al gestore eventi per visualizzare un elenco di studenti nel controllo ListBox.
Me.studentList.Items.Clear() ' Get the CourseID from the selected Course. Dim course As Course = CType(Me.courseList.SelectedItem, _ Course) Dim courseId As Integer = course.CourseID ' Get all StudentGrade objects for the supplied CourseID Dim studentQuery As Course = schoolContext.Courses.Where _ ("it.CourseID = @courseID", New ObjectParameter _ ("courseID", courseId)).Include("StudentGrades"). _ FirstOrDefault() ' Get all students for each StudentGrade For Each cg As StudentGrade In studentQuery.StudentGrades cg.PersonReference.Load() studentList.Items.Add(cg.Person.LastName + ", " + _ cg.Person.FirstName) Next studentList.Items.Add(" ") ' Get all Instructor types for the supplied CourseID Dim instructorQuery As Course = schoolContext.Courses. _ Where("it.CourseID = @courseID", New ObjectParameter _ ("courseID", courseId)).Include("People") _ .FirstOrDefault() ' Display each instructor for the specified Course For Each Instructor As Instructor In instructorQuery.People Me.studentList.Items.Add("Instructor: " + Instructor. _ LastName + ", " + Instructor.FirstName) Next
studentList.Items.Clear(); // Get the CourseID from the selected Course. Course course = (Course)courseList.SelectedItem; int courseId = course.CourseID; // Get all StudentGrade types for the supplied CourseID Course studentQuery = schoolContext.Courses.Where( "it.CourseID = @courseID", new ObjectParameter ("courseID", courseId)).Include("StudentGrades"). FirstOrDefault(); // Get all students for each StudentGrade foreach (StudentGrade sg in studentQuery.StudentGrades) { sg.PersonReference.Load(); studentList.Items.Add(sg.Person.LastName + ", " + sg.Person.FirstName); } studentList.Items.Add(" "); // Get all Instructor types for the supplied CourseID Course instructorQuery = schoolContext.Courses.Where( "it.CourseID = @courseID", new ObjectParameter ("courseID", courseId)).Include("People"). FirstOrDefault(); // Display each instructor for the specified course. foreach (Instructor instructor in instructorQuery.People. OfType<Instructor>()) { studentList.Items.Add("Instructor: " + instructor. LastName + ", " + instructor.FirstName); }
L'applicazione è ora completa. Premere Ctrl+F5 per eseguirla. Fare clic sul pulsante View Enrollment per caricare il form Enrollment. L'iscrizione al corso e i docenti per il corso selezionato sono visualizzati in ListBox.
Listato di codice
In questa sezione viene riportata la versione finale del file code-behind del form Enrollment.
Imports System.Data.Objects
Imports System.Data.Objects.DataClasses
Public Class Enrollment
' Create an ObjectContext instance based on SchoolEntity.
Private schoolContext As SchoolEntities
Private Sub Enrollment_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
' Initialize the ObjectContext.
schoolContext = New SchoolEntities()
' Define a query that returns all Department objects and
' related Course objects, ordered by name.
Dim departmentQuery As ObjectQuery(Of Department) = _
schoolContext.Departments.Include("Courses") _
.OrderBy("it.Name")
' Bind the ComboBox control to the query, which is
' executed during data binding.
Me.departmentList.DataSource = departmentQuery _
.Execute(MergeOption.OverwriteChanges)
Me.departmentList.DisplayMember = "Name"
End Sub
Private Sub departmentList_SelectedIndexChanged(ByVal sender _
As System.Object, ByVal e As System.EventArgs) Handles _
departmentList.SelectedIndexChanged
' Get the object for the selected department
Dim department As Department = CType(Me.departmentList _
.SelectedItem, Department)
' Bind the ComboBox control Course properties of
' the selected Department.
courseList.DataSource = department.Courses
courseList.DisplayMember = "Title"
End Sub
Private Sub courseList_SelectedIndexChanged(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles _
courseList.SelectedIndexChanged
Me.studentList.Items.Clear()
' Get the CourseID from the selected Course.
Dim course As Course = CType(Me.courseList.SelectedItem, _
Course)
Dim courseId As Integer = course.CourseID
' Get all StudentGrade objects for the supplied CourseID
Dim studentQuery As Course = schoolContext.Courses.Where _
("it.CourseID = @courseID", New ObjectParameter _
("courseID", courseId)).Include("StudentGrades"). _
FirstOrDefault()
' Get all students for each StudentGrade
For Each cg As StudentGrade In studentQuery.StudentGrades
cg.PersonReference.Load()
studentList.Items.Add(cg.Person.LastName + ", " + _
cg.Person.FirstName)
Next
studentList.Items.Add(" ")
' Get all Instructor types for the supplied CourseID
Dim instructorQuery As Course = schoolContext.Courses. _
Where("it.CourseID = @courseID", New ObjectParameter _
("courseID", courseId)).Include("People") _
.FirstOrDefault()
' Display each instructor for the specified Course
For Each Instructor As Instructor In instructorQuery.People
Me.studentList.Items.Add("Instructor: " + Instructor. _
LastName + ", " + Instructor.FirstName)
Next
End Sub
End Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
namespace CourseManager
{
public partial class Enrollment : Form
{
// Create an ObjectContext instance based on SchoolEntities.
private SchoolEntities schoolContext;
public Enrollment()
{
InitializeComponent();
}
private void Enrollment_Load(object sender, EventArgs e)
{
// Initialize the ObjectContext.
schoolContext = new SchoolEntities();
// Define a query that returns all Department objects
// and related Course objects, ordered by name.
ObjectQuery<Department> departmentQuery =
schoolContext.Departments.Include("Courses")
.OrderBy("it.Name");
// Bind the ComboBox control to the query.
this.departmentList.DataSource = departmentQuery
.Execute(MergeOption.OverwriteChanges);
this.departmentList.DisplayMember = "Name";
}
private void departmentList_SelectedIndexChanged(object sender,
EventArgs e)
{
// Get the object for the selected department.
Department department =
(Department)this.departmentList.SelectedItem;
// Bind the ComboBox control to the Course
// properties of the selected Department.
courseList.DataSource = department.Courses;
courseList.DisplayMember = "Title";
}
private void courseList_SelectedIndexChanged(object sender,
EventArgs e)
{
studentList.Items.Clear();
// Get the CourseID from the selected Course.
Course course = (Course)courseList.SelectedItem;
int courseId = course.CourseID;
// Get all StudentGrade types for the supplied CourseID
Course studentQuery = schoolContext.Courses.Where(
"it.CourseID = @courseID", new ObjectParameter
("courseID", courseId)).Include("StudentGrades").
FirstOrDefault();
// Get all students for each StudentGrade
foreach (StudentGrade sg in studentQuery.StudentGrades)
{
sg.PersonReference.Load();
studentList.Items.Add(sg.Person.LastName + ", " +
sg.Person.FirstName);
}
studentList.Items.Add(" ");
// Get all Instructor types for the supplied CourseID
Course instructorQuery = schoolContext.Courses.Where(
"it.CourseID = @courseID", new ObjectParameter
("courseID", courseId)).Include("People").
FirstOrDefault();
// Display each instructor for the specified course.
foreach (Instructor instructor in instructorQuery.People.
OfType<Instructor>())
{
studentList.Items.Add("Instructor: " + instructor.
LastName + ", " + instructor.FirstName);
}
}
}
}
Passaggi successivi
L'ereditarietà tabella per gerarchia in un modello concettuale è stata dunque implementata. Per ulteriori informazioni sulla definizione di un modello concettuale con ereditarietà della tabella per gerarchia, vedere How to: Define a Model with Table-per-Hierarchy Inheritance. Per ulteriori informazioni sulla compilazione di applicazioni con Entity Framework, vedere ADO.NET Entity Framework.
Vedere anche
Altre risorse
Scenari degli strumenti di Entity Data Model
Attività degli strumenti di Entity Data Model