Creazione di un modello di dati entity Framework per un'applicazione MVC di ASP.NET (1 di 10)
di Tom Dykstra
Nota
È disponibile una versione più recente di questa serie di esercitazioni per Visual Studio 2013, Entity Framework 6 e MVC 5.
L'applicazione Web di esempio Contoso University illustra come creare applicazioni ASP.NET MVC 4 usando Entity Framework 5 e Visual Studio 2012. L'applicazione di esempio è un sito Web per una fittizia Contoso University. Include funzionalità, come ad esempio l'ammissione di studenti, la creazione di corsi e le assegnazioni di insegnati. Questa serie di esercitazioni illustra come compilare l'applicazione di esempio Contoso University.
Code First
Esistono tre modi per usare i dati in Entity Framework: Database First, Model First e Code First. Questa esercitazione è per Code First. Per informazioni sulle differenze tra questi flussi di lavoro e indicazioni su come scegliere la soluzione migliore per lo scenario, vedere Flussi di lavoro di sviluppo di Entity Framework.
MVC
L'applicazione di esempio è basata su ASP.NET MVC. Se si preferisce usare il modello di Web Forms ASP.NET, vedere la serie di esercitazioni Di associazione di modelli e Web Forms e ASP.NETmappa del contenuto di accesso ai dati.
Versioni software
Illustrato nell'esercitazione Funziona anche con Windows 8 Windows 7 Visual Studio 2012 Visual Studio 2012 Express for Web. Questa operazione viene installata automaticamente da Windows Azure SDK se non si ha già VS 2012 o VS 2012 Express for Web. Visual Studio 2013 dovrebbe funzionare, ma l'esercitazione non è stata testata con essa e alcune selezioni di menu e finestre di dialogo sono diverse. La versione di VS 2013 di Windows Azure SDK è necessaria per la distribuzione di Windows Azure. .NET 4.5 La maggior parte delle funzionalità visualizzate funzionerà in .NET 4, ma alcuni non funzioneranno. Ad esempio, il supporto dell'enumerazione in EF richiede .NET 4.5. Entity Framework 5 Windows Azure SDK 2.1 Se si ignorano i passaggi di distribuzione di Windows Azure, non è necessario l'SDK. Quando viene rilasciata una nuova versione dell'SDK, il collegamento installerà la versione più recente. In questo caso, potrebbe essere necessario adattare alcune delle istruzioni alle nuove funzionalità e interfaccia utente. Domande
Se si hanno domande che non sono direttamente correlate all'esercitazione, è possibile pubblicarli nel forum ASP.NET Entity Framework, nel forum entity Framework e LINQ to Entities o StackOverflow.com.
Ringraziamenti
Vedere l'ultima esercitazione nella serie per i riconoscimenti e una nota su VB.
Applicazione Web Contoso University
L'applicazione che sarà compilata in queste esercitazioni è un semplice sito Web universitario.
Gli utenti possono visualizzare e aggiornare le informazioni che riguardano studenti, corsi e insegnanti. Di seguito sono disponibili alcune schermate che saranno create.
Lo stile dell'interfaccia utente del sito è simile a quanto è stato generato tramite i modelli predefiniti. L'esercitazione si concentra pertanto soprattutto sull'uso di Entity Framework.
Prerequisiti
Le istruzioni e le schermate in questa esercitazione presuppongono che si usi Visual Studio 2012 o Visual Studio 2012 Express for Web, con l'aggiornamento più recente e Azure SDK per .NET installato a partire da luglio 2013. È possibile ottenere tutto questo con il collegamento seguente:
Azure SDK per .NET (Visual Studio 2012)
Se Visual Studio è installato, il collegamento precedente installerà tutti i componenti mancanti. Se Visual Studio non è disponibile, il collegamento installerà Visual Studio 2012 Express for Web. È possibile usare Visual Studio 2013, ma alcune delle procedure e delle schermate necessarie saranno diverse.
Creare un'applicazione Web MVC
Aprire Visual Studio e creare un nuovo progetto C# denominato "ContosoUniversity" usando il modello di applicazione Web MVC 4 ASP.NET MVC 4 . Assicurarsi di avere come destinazione .NET Framework 4.5 (si useranno enum
le proprietà e che richiedono .NET 4.5).
Nella finestra di dialogo Nuovo ASP.NET progetto MVC 4 selezionare il modello applicazione Internet .
Lasciare selezionato il motore di visualizzazione Razor e lasciare deselezionata la casella di controllo Crea un progetto di unit test .
Fare clic su OK.
Configurare lo stile del sito
Con alcune modifiche è possibile impostare il menu del sito, il layout e la home page.
Aprire Views\Shared\_Layout.cshtml e sostituire il contenuto del file con il codice seguente. Le modifiche sono evidenziate.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title - Contoso University</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<header>
<div class="content-wrapper">
<div class="float-left">
<p class="site-title">@Html.ActionLink("Contoso University", "Index", "Home")</p>
</div>
<div class="float-right">
<section id="login">
@Html.Partial("_LoginPartial")
</section>
<nav>
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Students", "Index", "Student")</li>
<li>@Html.ActionLink("Courses", "Index", "Course")</li>
<li>@Html.ActionLink("Instructors", "Index", "Instructor")</li>
<li>@Html.ActionLink("Departments", "Index", "Department")</li>
</ul>
</nav>
</div>
</div>
</header>
<div id="body">
@RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
@RenderBody()
</section>
</div>
<footer>
<div class="content-wrapper">
<div class="float-left">
<p>© @DateTime.Now.Year - Contoso University</p>
</div>
</div>
</footer>
@Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)
</body>
</html>
Questo codice apporta le modifiche seguenti:
- Sostituisce le istanze del modello di "My ASP.NET MVC Application" e "your logo here" con "Contoso University".
- Aggiunge diversi collegamenti di azione che verranno usati più avanti nell'esercitazione.
In Views\Home\Index.cshtml sostituire il contenuto del file con il codice seguente per eliminare i paragrafi del modello relativi a ASP.NET e MVC:
@{
ViewBag.Title = "Home Page";
}
@section featured {
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
<h2>@ViewBag.Message</h2>
</hgroup>
</div>
</section>
}
In Controller\HomeController.cs modificare il valore per ViewBag.Message
nel metodo Action in "Welcome to Contoso University!", come illustrato nell'esempio Index
seguente:
public ActionResult Index()
{
ViewBag.Message = "Welcome to Contoso University";
return View();
}
Premere CTRL+F5 per eseguire il sito. Viene visualizzata la home page con il menu principale.
Creare il modello di dati
A questo punto è possibile creare le classi delle entità per l'applicazione di Contoso University. Si inizierà con le tre entità seguenti:
Esiste una relazione uno-a-molti tra le entità Student
e Enrollment
ed esiste una relazione uno-a-molti tra le entità Course
e Enrollment
. In altre parole, uno studente può iscriversi a un numero qualsiasi di corsi e un corso può avere un numero qualsiasi di studenti iscritti.
Nelle sezioni seguenti viene creata una classe per ognuna di queste entità.
Nota
Se si tenta di compilare il progetto prima di completare la creazione di tutte queste classi di entità, si otterranno errori del compilatore.
Entità studente
Nella cartella Modelli creare Student.cs e sostituire il codice esistente con il codice seguente:
using System;
using System.Collections.Generic;
namespace ContosoUniversity.Models
{
public class Student
{
public int StudentID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}
La proprietà StudentID
diventa la colonna di chiave primaria della tabella di database che corrisponde a questa classe. Per impostazione predefinita, Entity Framework interpreta una proprietà denominata o nome ID
classeID
come chiave primaria.
La proprietà Enrollments
rappresenta una proprietà di navigazione. Le proprietà di navigazione contengono altre entità correlate a questa entità. In questo caso, la Enrollments
proprietà di un'entità Student
conterrà tutte le Enrollment
entità correlate a tale Student
entità. In altre parole, se una Student
determinata riga nel database ha due righe correlate Enrollment
(righe che contengono il valore della chiave primaria dello studente nella StudentID
colonna chiave esterna), la Student
proprietà di spostamento dell'entità Enrollments
conterrà queste due Enrollment
entità.
Le proprietà di spostamento vengono in genere definite in virtual
modo che possano sfruttare determinate funzionalità di Entity Framework, ad esempio il caricamento lazy. Il caricamento lazy verrà spiegato più avanti nell'esercitazione Lettura dei dati correlati più avanti in questa serie.
Se una proprietà di navigazione può contenere più entità (come nel caso di relazioni molti-a-molti e uno-a-molti), il tipo della proprietà deve essere un elenco in cui le voci possono essere aggiunte, eliminate e aggiornate, come ad esempio ICollection
.
Entità registrazione
Nella cartella Models creare Enrollment.cs e sostituire il codice esistente con il codice seguente:
namespace ContosoUniversity.Models
{
public enum Grade
{
A, B, C, D, F
}
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public virtual Course Course { get; set; }
public virtual Student Student { get; set; }
}
}
La proprietà Grade è un'enumerazione. Il punto interrogativo dopo la dichiarazione del tipo Grade
indica che la proprietà Grade
ammette i valori Null. Un grado null è diverso da un livello zero: null significa che un grado non è noto o non è ancora stato assegnato.
La proprietà StudentID
è una chiave esterna e la proprietà di navigazione corrispondente è Student
. Un'entità Enrollment
è associata a un'entità Student
, pertanto la proprietà può contenere un'unica entità Student
, a differenza della proprietà di navigazione Student.Enrollments
vista in precedenza, che può contenere più entità Enrollment
.
La proprietà CourseID
è una chiave esterna e la proprietà di navigazione corrispondente è Course
. Un'entità Enrollment
è associata a un'entità Course
.
Entità Course
Nella cartella Modelli creare Course.cs sostituendo il codice esistente con il codice seguente:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}
La proprietà Enrollments
rappresenta una proprietà di navigazione. È possibile correlare un'entità Course
a un numero qualsiasi di entità Enrollment
.
Verranno fornite altre informazioni su [DatabaseGenerated(DatabaseGeneratedOption). Attributo None)] nell'esercitazione successiva. In pratica, questo attributo consente di immettere la chiave primaria per il corso invece di essere generata dal database.
Creare il contesto di database
La classe principale che coordina la funzionalità di Entity Framework per un determinato modello di dati è la classe di contesto del database . Questa classe viene creata derivando dalla classe System.Data.Entity.DbContext . Nel codice vengono specificate le entità incluse nel modello di dati. È anche possibile personalizzare un determinato comportamento di Entity Framework. In questo progetto la classe è denominata SchoolContext
.
Creare una cartella denominata DAL (per Livello di accesso ai dati). In tale cartella creare un nuovo file di classe denominato SchoolContext.cs e sostituire il codice esistente con il codice seguente:
using ContosoUniversity.Models;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace ContosoUniversity.DAL
{
public class SchoolContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Questo codice crea una proprietà DbSet per ogni set di entità. Nella terminologia di Entity Framework un set di entità corrisponde in genere a una tabella di database e un'entità corrisponde a una riga nella tabella.
L'istruzione modelBuilder.Conventions.Remove
nel metodo OnModelCreating impedisce che i nomi di tabella vengano pluralizzati. Se non è stata eseguita questa operazione, le tabelle generate verranno denominate Students
, Courses
e Enrollments
. Invece, i nomi delle tabelle saranno Student
, Course
e Enrollment
. Gli sviluppatori non hanno un'opinione unanime sul fatto che i nomi di tabella debbano essere pluralizzati oppure no. Questa esercitazione usa il modulo singolare, ma il punto importante è che è possibile selezionare il modulo preferito includendo o omettendo questa riga di codice.
SQL Server Express LocalDB
LocalDB è una versione leggera del motore di database di SQL Server Express che avvia su richiesta ed esegue in modalità utente. LocalDB viene eseguito in una modalità di esecuzione speciale di SQL Server Express che consente di usare i database come file di .mdf. In genere, i file di database LocalDB vengono mantenuti nella cartella App_Data di un progetto Web. La funzionalità dell'istanza utente in SQL Server Express consente anche di usare i file di .mdf, ma la funzionalità dell'istanza utente è deprecata. Pertanto, LocalDB è consigliabile usare i file .mdf.
In genere SQL Server Express non viene usato per le applicazioni Web di produzione. LocalDB in particolare non è consigliato per l'uso di produzione con un'applicazione Web perché non è progettato per l'uso con IIS.
In Visual Studio 2012 e versioni successive, LocalDB viene installato per impostazione predefinita con Visual Studio. In Visual Studio 2010 e versioni precedenti, SQL Server Express (senza LocalDB) viene installato per impostazione predefinita con Visual Studio. Se si usa Visual Studio 2010, è necessario installarlo manualmente.
In questa esercitazione si userà LocalDB in modo che il database possa essere archiviato nella cartella App_Data come file di .mdf. Aprire il file radiceWeb.confige aggiungere una nuova stringa di connessione alla raccolta, come illustrato nell'esempio connectionStrings
seguente. Assicurarsi di aggiornare il file diWeb.config nella cartella del progetto radice. È disponibile anche un file Web.config nella sottocartella Visualizzazioni che non è necessario aggiornare.
<add name="SchoolContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ContosoUniversity;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\ContosoUniversity.mdf" providerName="System.Data.SqlClient" />
Per impostazione predefinita, Entity Framework cerca un stringa di connessione denominato uguale DbContext
alla classe (SchoolContext
per questo progetto). Il stringa di connessione aggiunto specifica un database LocalDB denominato ContosoUniversity.mdf situato nella cartella App_Data. Per altre informazioni, vedere SQL Server stringhe di connessione per applicazioni Web ASP.NET.
Non è effettivamente necessario specificare il stringa di connessione. Se non si specifica un stringa di connessione, Entity Framework creerà uno per l'utente. Tuttavia, il database potrebbe non trovarsi nella cartella App_data dell'app. Per informazioni sulla posizione in cui verrà creato il database, vedere Code First to a New Database .For information on where the database will be create, see Code First to a New Database.
La connectionStrings
raccolta include anche un stringa di connessione denominato DefaultConnection
che viene usato per il database di appartenenza. Non si usa il database di appartenenza in questa esercitazione. L'unica differenza tra le due stringhe di connessione è il nome del database e il valore dell'attributo name.
Configurare ed eseguire una prima migrazione del codice
Quando si inizia a sviluppare un'applicazione, il modello di dati cambia frequentemente e ogni volta che il modello cambia la sincronizzazione con il database. È possibile configurare Entity Framework per eliminare e ricreare automaticamente il database ogni volta che si modifica il modello di dati. Questo non è un problema all'inizio dello sviluppo perché i dati di test vengono facilmente creati, ma dopo aver distribuito in produzione si vuole in genere aggiornare lo schema del database senza eliminare il database. La funzionalità Migrazione consente a Code First di aggiornare il database senza eliminarlo e ricrearlo. All'inizio del ciclo di sviluppo di un nuovo progetto, è possibile usare DropCreateDatabaseIfModelChanges per eliminare, ricreare e ri-inizializzare il database ogni volta che il modello cambia. Si è pronti per distribuire l'applicazione, è possibile convertire nell'approccio delle migrazioni. Per questa esercitazione si useranno solo le migrazioni. Per altre informazioni, vedere Migrazioni Code First e serie screencast delle migrazioni.
Abilitare Migrazioni Code First
Dal menu Strumenti fare clic su Gestione pacchetti NuGet e quindi console di Gestione pacchetti.
Al prompt immettere il
PM>
comando seguente:enable-migrations -contexttypename SchoolContext
Questo comando crea una cartella Migrations nel progetto ContosoUniversity e inserisce in tale cartella un file Configuration.cs che è possibile modificare per configurare le migrazioni.
La
Configuration
classe include unSeed
metodo chiamato quando il database viene creato e ogni volta che viene aggiornato dopo una modifica del modello di dati.internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.Models.SchoolContext> { public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(ContosoUniversity.Models.SchoolContext context) { // This method will be called after migrating to the latest version. // You can use the DbSet<T>.AddOrUpdate() helper extension method // to avoid creating duplicate seed data. E.g. // // context.People.AddOrUpdate( // p => p.FullName, // new Person { FullName = "Andrew Peters" }, // new Person { FullName = "Brice Lambson" }, // new Person { FullName = "Rowan Miller" } // ); // } }
Lo scopo di questo
Seed
metodo consiste nell'inserire i dati di test nel database dopo che Code First lo crea o lo aggiorna.
Configurare il metodo seed
Il metodo Seed viene eseguito quando Migrazioni Code First crea il database e ogni volta che aggiorna il database alla migrazione più recente. Lo scopo del metodo Seed consiste nell'inserire i dati nelle tabelle prima che l'applicazione acceda al database per la prima volta.
Nelle versioni precedenti di Code First, prima che le migrazioni siano state rilasciate, è stato comune Seed
inserire i dati di test, perché con ogni modifica del modello durante lo sviluppo il database deve essere completamente eliminato e ricreato da zero. Con Migrazioni Code First, i dati di test vengono mantenuti dopo le modifiche del database, quindi i dati di test nel metodo Seed non sono in genere necessari. In effetti, non si vuole che il metodo inserisca i dati di test se si useranno Le migrazioni per distribuire il Seed
database in produzione, perché il Seed
metodo verrà eseguito in produzione. In tal caso si vuole che il Seed
metodo inserisca nel database solo i dati da inserire nell'ambiente di produzione. Ad esempio, è possibile che il database includa nomi di reparto effettivi nella Department
tabella quando l'applicazione diventa disponibile in produzione.
Per questa esercitazione si useranno Migrazioni per la distribuzione, ma il Seed
metodo inserisce comunque i dati di test per semplificare il funzionamento delle funzionalità dell'applicazione senza dover inserire manualmente molti dati.
Sostituire il contenuto del file Configuration.cs con il codice seguente, che caricherà i dati di test nel nuovo database.
namespace ContosoUniversity.Migrations { using System; using System.Collections.Generic; using System.Data.Entity.Migrations; using System.Linq; using ContosoUniversity.Models; internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.DAL.SchoolContext> { public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(ContosoUniversity.DAL.SchoolContext context) { var students = new List<Student> { new Student { FirstMidName = "Carson", LastName = "Alexander", EnrollmentDate = DateTime.Parse("2010-09-01") }, new Student { FirstMidName = "Meredith", LastName = "Alonso", EnrollmentDate = DateTime.Parse("2012-09-01") }, new Student { FirstMidName = "Arturo", LastName = "Anand", EnrollmentDate = DateTime.Parse("2013-09-01") }, new Student { FirstMidName = "Gytis", LastName = "Barzdukas", EnrollmentDate = DateTime.Parse("2012-09-01") }, new Student { FirstMidName = "Yan", LastName = "Li", EnrollmentDate = DateTime.Parse("2012-09-01") }, new Student { FirstMidName = "Peggy", LastName = "Justice", EnrollmentDate = DateTime.Parse("2011-09-01") }, new Student { FirstMidName = "Laura", LastName = "Norman", EnrollmentDate = DateTime.Parse("2013-09-01") }, new Student { FirstMidName = "Nino", LastName = "Olivetto", EnrollmentDate = DateTime.Parse("2005-08-11") } }; students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, s)); context.SaveChanges(); var courses = new List<Course> { new Course {CourseID = 1050, Title = "Chemistry", Credits = 3, }, new Course {CourseID = 4022, Title = "Microeconomics", Credits = 3, }, new Course {CourseID = 4041, Title = "Macroeconomics", Credits = 3, }, new Course {CourseID = 1045, Title = "Calculus", Credits = 4, }, new Course {CourseID = 3141, Title = "Trigonometry", Credits = 4, }, new Course {CourseID = 2021, Title = "Composition", Credits = 3, }, new Course {CourseID = 2042, Title = "Literature", Credits = 4, } }; courses.ForEach(s => context.Courses.AddOrUpdate(p => p.Title, s)); context.SaveChanges(); var enrollments = new List<Enrollment> { new Enrollment { StudentID = students.Single(s => s.LastName == "Alexander").StudentID, CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID, Grade = Grade.A }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alexander").StudentID, CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID, Grade = Grade.C }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alexander").StudentID, CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alonso").StudentID, CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alonso").StudentID, CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alonso").StudentID, CourseID = courses.Single(c => c.Title == "Composition" ).CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Anand").StudentID, CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID }, new Enrollment { StudentID = students.Single(s => s.LastName == "Anand").StudentID, CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Barzdukas").StudentID, CourseID = courses.Single(c => c.Title == "Chemistry").CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Li").StudentID, CourseID = courses.Single(c => c.Title == "Composition").CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Justice").StudentID, CourseID = courses.Single(c => c.Title == "Literature").CourseID, Grade = Grade.B } }; foreach (Enrollment e in enrollments) { var enrollmentInDataBase = context.Enrollments.Where( s => s.Student.StudentID == e.StudentID && s.Course.CourseID == e.CourseID).SingleOrDefault(); if (enrollmentInDataBase == null) { context.Enrollments.Add(e); } } context.SaveChanges(); } } }
Il metodo Seed accetta l'oggetto contesto del database come parametro di input e il codice nel metodo usa tale oggetto per aggiungere nuove entità al database. Per ogni tipo di entità, il codice crea una raccolta di nuove entità, le aggiunge alla proprietà DbSet appropriata e quindi salva le modifiche al database. Non è necessario chiamare il metodo SaveChanges dopo ogni gruppo di entità, come avviene qui, ma ciò consente di individuare l'origine di un problema se si verifica un'eccezione durante la scrittura del codice nel database.
Alcune istruzioni che inseriscono i dati usano il metodo AddOrUpdate per eseguire un'operazione "upsert". Poiché il
Seed
metodo viene eseguito con ogni migrazione, non è possibile inserire solo i dati, perché le righe che si sta tentando di aggiungere saranno già presenti dopo la prima migrazione che crea il database. L'operazione "upsert" impedisce errori che si verificherebbero se si tenta di inserire una riga già esistente, ma esegue l'override delle modifiche apportate ai dati che potrebbero essere state apportate durante il test dell'applicazione. Con i dati di test in alcune tabelle potrebbe non essere necessario eseguire questa operazione: in alcuni casi quando si modificano i dati durante il test delle modifiche che si desidera che le modifiche rimangano dopo gli aggiornamenti del database. In questo caso si vuole eseguire un'operazione di inserimento condizionale: inserire una riga solo se non esiste già. Il metodo Seed usa entrambi gli approcci.Il primo parametro passato al metodo AddOrUpdate specifica la proprietà da usare per verificare se esiste già una riga. Per i dati degli studenti di test specificati, la
LastName
proprietà può essere usata per questo scopo poiché ogni cognome nell'elenco è univoco:context.Students.AddOrUpdate(p => p.LastName, s)
Questo codice presuppone che gli ultimi nomi siano univoci. Se si aggiunge manualmente uno studente con un cognome duplicato, si otterrà l'eccezione seguente alla successiva esecuzione di una migrazione.
La sequenza contiene più di un elemento
Per altre informazioni sul metodo, vedere Prendere cura del metodo EF 4.3 AddOrUpdate nel blog di Julie Lerman.
AddOrUpdate
Il codice che aggiunge
Enrollment
entità non usa ilAddOrUpdate
metodo . Verifica se esiste già un'entità e inserisce l'entità se non esiste. Questo approccio mantiene le modifiche apportate a un livello di registrazione durante l'esecuzione delle migrazioni. Il codice scorre attraverso ogni membro dell'elencoEnrollment
e se la registrazione non viene trovata nel database, aggiunge la registrazione al database. La prima volta che si aggiorna il database, il database sarà vuoto, quindi aggiungerà ogni registrazione.foreach (Enrollment e in enrollments) { var enrollmentInDataBase = context.Enrollments.Where( s => s.Student.StudentID == e.Student.StudentID && s.Course.CourseID == e.Course.CourseID).SingleOrDefault(); if (enrollmentInDataBase == null) { context.Enrollments.Add(e); } }
Per informazioni su come eseguire il debug del
Seed
metodo e su come gestire i dati ridondanti, ad esempio due studenti denominati "Alexander Carson", vedere Seeding and Debug Entity Framework (EF) nel blog di Rick Anderson.Compilare il progetto.
Creare ed eseguire la prima migrazione
Nella finestra Console di Gestione pacchetti immettere i comandi seguenti:
add-migration InitialCreate update-database
Il
add-migration
comando aggiunge alla cartella Migrations un file [DateStamp]_InitialCreate.cs che contiene il codice che crea il database. Il primo parametro (InitialCreate)
viene usato per il nome del file e può essere qualsiasi elemento desiderato; in genere si sceglie una parola o una frase che riepiloga le operazioni eseguite nella migrazione. Ad esempio, è possibile denominare una migrazione successiva "AddDepartmentTable".Il
Up
metodo dellaInitialCreate
classe crea le tabelle di database che corrispondono ai set di entità del modello di dati e ilDown
metodo li elimina. Le migrazioni chiamano il metodoUp
per implementare le modifiche al modello di dati per una migrazione. Quando si immette un comando per annullare l'aggiornamento, le migrazioni chiamano il metodoDown
. Il codice seguente mostra il contenuto delInitialCreate
file:namespace ContosoUniversity.Migrations { using System; using System.Data.Entity.Migrations; public partial class InitialCreate : DbMigration { public override void Up() { CreateTable( "dbo.Student", c => new { StudentID = c.Int(nullable: false, identity: true), LastName = c.String(), FirstMidName = c.String(), EnrollmentDate = c.DateTime(nullable: false), }) .PrimaryKey(t => t.StudentID); CreateTable( "dbo.Enrollment", c => new { EnrollmentID = c.Int(nullable: false, identity: true), CourseID = c.Int(nullable: false), StudentID = c.Int(nullable: false), Grade = c.Int(), }) .PrimaryKey(t => t.EnrollmentID) .ForeignKey("dbo.Course", t => t.CourseID, cascadeDelete: true) .ForeignKey("dbo.Student", t => t.StudentID, cascadeDelete: true) .Index(t => t.CourseID) .Index(t => t.StudentID); CreateTable( "dbo.Course", c => new { CourseID = c.Int(nullable: false), Title = c.String(), Credits = c.Int(nullable: false), }) .PrimaryKey(t => t.CourseID); } public override void Down() { DropIndex("dbo.Enrollment", new[] { "StudentID" }); DropIndex("dbo.Enrollment", new[] { "CourseID" }); DropForeignKey("dbo.Enrollment", "StudentID", "dbo.Student"); DropForeignKey("dbo.Enrollment", "CourseID", "dbo.Course"); DropTable("dbo.Course"); DropTable("dbo.Enrollment"); DropTable("dbo.Student"); } } }
Il
update-database
comando esegue ilUp
metodo per creare il database e quindi esegue ilSeed
metodo per popolare il database.
È stato creato un database SQL Server per il modello di dati. Il nome del database è ContosoUniversity e il file .mdf si trova nella cartella App_Data del progetto, perché questo è quello specificato nel stringa di connessione.
È possibile usare Esplora server o SQL Server Esplora oggetti (SSOX) per visualizzare il database in Visual Studio. Per questa esercitazione si userà Esplora server. In Visual Studio Express 2012 per Il Web, Esplora server è denominato Esplora database.
Scegliere Esplora server dal menu Visualizza.
Fare clic sull'icona Aggiungi connessione .
Se viene visualizzata la finestra di dialogo Scegli origine dati, fare clic su Microsoft SQL Server e quindi fare clic su Continua.
Nella finestra di dialogo Aggiungi connessione immettere (localdb)\v11.0 come Nome server. In Selezionare o immettere un nome di database selezionare ContosoUniversity.
Scegliere OK.
Espandere SchoolContext e quindi tabelle.
Fare clic con il pulsante destro del mouse sulla tabella Student e scegliere Mostra dati tabella per visualizzare le colonne create e le righe inserite nella tabella.
Creazione di un controller e visualizzazioni per studenti
Il passaggio successivo consiste nel creare un controller e viste MVC ASP.NET nell'applicazione che possono essere usati con una di queste tabelle.
Per creare un
Student
controller, fare clic con il pulsante destro del mouse sulla cartella Controller in Esplora soluzioni, scegliere Aggiungi e quindi fare clic su Controller. Nella finestra di dialogo Aggiungi controller effettuare le selezioni seguenti e quindi fare clic su Aggiungi:Nome controller: StudentController.
Modello: controller MVC con azioni e viste di lettura/scrittura, usando Entity Framework.
Classe modello: Student (ContosoUniversity.Models). Se questa opzione non viene visualizzata nell'elenco a discesa, compilare il progetto e riprovare.
Classe contesto dati: SchoolContext (ContosoUniversity.Models).
Views: Razor (CSHTML). Impostazione predefinita.
Visual Studio apre il file Controllers\StudentController.cs . Viene visualizzata la creazione di una variabile di classe che crea un'istanza di un oggetto contesto di database:
private SchoolContext db = new SchoolContext();
Il
Index
metodo di azione ottiene un elenco di studenti dal set di entità Students leggendo laStudents
proprietà dell'istanza del contesto di database:public ViewResult Index() { return View(db.Students.ToList()); }
La visualizzazione Student\Index.cshtml visualizza questo elenco in una tabella:
<table> <tr> <th> @Html.DisplayNameFor(model => model.LastName) </th> <th> @Html.DisplayNameFor(model => model.FirstMidName) </th> <th> @Html.DisplayNameFor(model => model.EnrollmentDate) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.LastName) </td> <td> @Html.DisplayFor(modelItem => item.FirstMidName) </td> <td> @Html.DisplayFor(modelItem => item.EnrollmentDate) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) | @Html.ActionLink("Details", "Details", new { id=item.StudentID }) | @Html.ActionLink("Delete", "Delete", new { id=item.StudentID }) </td> </tr> }
Premere CTRL+F5 per eseguire il progetto.
Fare clic sulla scheda Students (Studenti) per visualizzare i dati di test inseriti dal
Seed
metodo.
Convenzioni
La quantità di codice che è necessario scrivere affinché Entity Framework sia in grado di creare un database completo è minimo a causa dell'uso di convenzioni o presupposti creati da Entity Framework. Alcuni di essi sono già stati annotati:
- Le forme pluralizzate di nomi di classi di entità vengono usate come nomi di tabella.
- I nomi della proprietà di entità vengono usati come nomi di colonna.
- Le proprietà di entità denominate
ID
o classnameID
vengono riconosciute come proprietà della chiave primaria.
Si è visto che è possibile eseguire l'override delle convenzioni(ad esempio, è stato specificato che i nomi di tabella non devono essere pluralizzati) e si apprenderà come eseguire l'override delle convenzioni nell'esercitazione Creazione di un modello di dati più complesso più avanti in questa serie. Per altre informazioni, vedere Code First Conventions.
Riepilogo
È stata creata una semplice applicazione che usa Entity Framework e SQL Server Express per archiviare e visualizzare i dati. Nell'esercitazione seguente si apprenderà come eseguire operazioni CRUD di base (creazione, lettura, aggiornamento, eliminazione). È possibile lasciare commenti e suggerimenti nella parte inferiore di questa pagina. Fateci sapere come è piaciuta questa parte dell'esercitazione e come potremmo migliorarla.
I collegamenti ad altre risorse di Entity Framework sono disponibili nella mappa del contenuto ASP.NET accesso ai dati.
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per