Scenari avanzati di Entity Framework per un'applicazione Web MVC (10 di 10)
di Tom Dykstra
L'applicazione Web di esempio Contoso University illustra come creare ASP.NET applicazioni MVC 4 usando Entity Framework 5 Code First e Visual Studio 2012. Per informazioni sulla serie di esercitazioni, vedere la prima esercitazione della serie.
Nota
Se si verifica un problema che non è possibile risolvere, scaricare il capitolo completato e provare a riprodurre il problema. In genere è possibile trovare la soluzione al problema confrontando il codice con il codice completato. Per alcuni errori comuni e come risolverli, vedere Errori e soluzioni alternative.
Nell'esercitazione precedente sono stati implementati il repository e l'unità di modelli di lavoro. Questa esercitazione illustra gli argomenti seguenti:
- Esecuzione di query SQL non elaborate.
- Esecuzione di query senza rilevamento.
- Esame delle query inviate al database.
- Uso delle classi proxy.
- Disabilitazione del rilevamento automatico delle modifiche.
- Disabilitazione della convalida durante il salvataggio delle modifiche.
- Errori e soluzione alternativa
Per la maggior parte di questi argomenti, si useranno le pagine già create. Per usare SQL non elaborato per eseguire aggiornamenti in blocco, si creerà una nuova pagina che aggiorna il numero di crediti di tutti i corsi nel database:
Per usare una query senza rilevamento, aggiungere una nuova logica di convalida alla pagina Modifica reparto:
Esecuzione di query SQL non elaborate
L'API Code First di Entity Framework include metodi che consentono di passare i comandi SQL direttamente al database. Sono disponibili le seguenti opzioni:
- Usare il metodo
DbSet.SqlQuery
per le query che restituiscono tipi di entità. Gli oggetti restituiti devono essere del tipo previsto dall'oggettoDbSet
e vengono rilevati automaticamente dal contesto del database, a meno che non si disattiva il rilevamento. Vedere la sezione seguente sulAsNoTracking
metodo . - Usare il
Database.SqlQuery
metodo per le query che restituiscono tipi che non sono entità. I dati restituiti non vengono registrati dal contesto di database, anche se il metodo viene usato per recuperare i tipi di entità. - Usare Database.ExecuteSqlCommand per i comandi non di query.
Uno dei vantaggi dell'utilizzo di Entity Framework è la mancanza di un collegamento troppo stretto del codice a un particolare metodo di archiviazione dei dati. Le query e i comandi SQL vengono generati automaticamente e non è necessario scriverli. Esistono tuttavia scenari eccezionali quando è necessario eseguire query SQL specifiche create manualmente e questi metodi consentono di gestire tali eccezioni.
Come avviene quando si eseguono comandi SQL in un'applicazione Web, è necessario adottare delle precauzioni per proteggere il sito dagli attacchi SQL injection. A questo scopo è possibile usare query parametrizzate per assicurarsi che le stringhe inviate da una pagina Web non possano essere interpretate come comandi SQL. In questa esercitazione verranno usate query parametrizzate quando l'input dell'utente viene integrato in una query.
Chiamata di una query che restituisce entità
Si supponga di voler consentire alla GenericRepository
classe di offrire ulteriore flessibilità di filtro e ordinamento senza richiedere la creazione di una classe derivata con metodi aggiuntivi. Un modo per ottenere questo risultato consiste nell'aggiungere un metodo che accetta una query SQL. È quindi possibile specificare qualsiasi tipo di filtro o ordinamento desiderato nel controller, ad esempio una Where
clausola che dipende da un join o da una sottoquery. In questa sezione verrà illustrato come implementare un metodo di questo tipo.
Creare il GetWithRawSql
metodo aggiungendo il codice seguente a GenericRepository.cs:
public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
return dbSet.SqlQuery(query, parameters).ToList();
}
In CourseController.cs chiamare il nuovo metodo dal Details
metodo , come illustrato nell'esempio seguente:
public ActionResult Details(int id)
{
var query = "SELECT * FROM Course WHERE CourseID = @p0";
return View(unitOfWork.CourseRepository.GetWithRawSql(query, id).Single());
}
In questo caso è possibile usare il GetByID
metodo , ma si usa il GetWithRawSql
metodo per verificare che il GetWithRawSQL
metodo funzioni.
Eseguire la pagina Dettagli per verificare che la query di selezione funzioni (selezionare la scheda Corso e quindi Dettagli per un corso).
Chiamata di una query che restituisce altri tipi di oggetti
In precedenza è stata creata una griglia delle statistiche degli studenti per la pagina About che visualizza il numero di studenti per ogni data di registrazione. Il codice che esegue questa operazione in HomeController.cs usa LINQ:
var data = from student in db.Students
group student by student.EnrollmentDate into dateGroup
select new EnrollmentDateGroup()
{
EnrollmentDate = dateGroup.Key,
StudentCount = dateGroup.Count()
};
Si supponga di voler scrivere il codice che recupera questi dati direttamente in SQL anziché usare LINQ. A tale scopo, è necessario eseguire una query che restituisce un valore diverso dagli oggetti entità, il che significa che è necessario usare il Database.SqlQuery
metodo .
In HomeController.cs sostituire l'istruzione LINQ nel About
metodo con il codice seguente:
var query = "SELECT EnrollmentDate, COUNT(*) AS StudentCount "
+ "FROM Person "
+ "WHERE EnrollmentDate IS NOT NULL "
+ "GROUP BY EnrollmentDate";
var data = db.Database.SqlQuery<EnrollmentDateGroup>(query);
Eseguire la pagina Informazioni su. Vengono visualizzati gli stessi dati visualizzati in precedenza.
Chiamata di una query di aggiornamento
Si supponga che gli amministratori di Contoso University vogliano essere in grado di eseguire modifiche in blocco nel database, ad esempio la modifica del numero di crediti per ogni corso. Se il numero di corsi dell'università è elevato, potrebbe non essere utile recuperarli tutti come entità e modificarli singolarmente. In questa sezione si implementerà una pagina Web che consente all'utente di specificare un fattore in base al quale modificare il numero di crediti per tutti i corsi e apportare la modifica eseguendo un'istruzione SQL UPDATE
. La pagina Web apparirà come segue:
Nell'esercitazione precedente è stato usato il repository generico per leggere e aggiornare Course
le entità nel Course
controller. Per questa operazione di aggiornamento in blocco, è necessario creare un nuovo metodo di repository che non si trova nel repository generico. A tale scopo, si creerà una classe dedicata CourseRepository
che deriva dalla GenericRepository
classe .
Nella cartella DAL creare CourseRepository.cs e sostituire il codice esistente con il codice seguente:
using System;
using ContosoUniversity.Models;
namespace ContosoUniversity.DAL
{
public class CourseRepository : GenericRepository<Course>
{
public CourseRepository(SchoolContext context)
: base(context)
{
}
public int UpdateCourseCredits(int multiplier)
{
return context.Database.ExecuteSqlCommand("UPDATE Course SET Credits = Credits * {0}", multiplier);
}
}
}
In UnitOfWork.cs modificare il Course
tipo di repository da GenericRepository<Course>
aCourseRepository:
private CourseRepository courseRepository;
public CourseRepository CourseRepository
{
get
{
if (this.courseRepository == null)
{
this.courseRepository = new CourseRepository(context);
}
return courseRepository;
}
}
In CourseController.cs aggiungere un UpdateCourseCredits
metodo:
public ActionResult UpdateCourseCredits(int? multiplier)
{
if (multiplier != null)
{
ViewBag.RowsAffected = unitOfWork.CourseRepository.UpdateCourseCredits(multiplier.Value);
}
return View();
}
Questo metodo verrà usato sia per che HttpPost
per HttpGet
. Quando viene eseguito il HttpGet
UpdateCourseCredits
metodo, la multiplier
variabile sarà Null e la visualizzazione visualizzerà una casella di testo vuota e un pulsante di invio, come illustrato nella figura precedente.
Quando si fa clic sul pulsante Aggiorna e il HttpPost
metodo viene eseguito, multiplier
il valore immesso nella casella di testo verrà immesso. Il codice chiama quindi il metodo del repository UpdateCourseCredits
, che restituisce il numero di righe interessate e tale valore viene archiviato nell'oggetto ViewBag
. Quando la visualizzazione riceve il numero di righe interessate nell'oggetto ViewBag
, visualizza tale numero anziché la casella di testo e il pulsante invia, come illustrato nella figura seguente:
Creare una visualizzazione nella cartella Views\Course per la pagina Update Course Credits :Create a view in the Views\Course folder for the Update Course Credits page:
In Views\Course\UpdateCourseCredits.cshtml sostituire il codice del modello con il codice seguente:
@model ContosoUniversity.Models.Course
@{
ViewBag.Title = "UpdateCourseCredits";
}
<h2>Update Course Credits</h2>
@if (ViewBag.RowsAffected == null)
{
using (Html.BeginForm())
{
<p>
Enter a number to multiply every course's credits by: @Html.TextBox("multiplier")
</p>
<p>
<input type="submit" value="Update" />
</p>
}
}
@if (ViewBag.RowsAffected != null)
{
<p>
Number of rows updated: @ViewBag.RowsAffected
</p>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Eseguire il metodo UpdateCourseCredits
selezionando la scheda Courses, quindi aggiungendo "/UpdateCourseCredits" alla fine dell'URL nella barra degli indirizzi del browser (ad esempio: http://localhost:50205/Course/UpdateCourseCredits
). Immettere un numero nella casella di testo:
Fai clic su Aggiorna. Viene visualizzato il numero di righe interessate:
Fare clic su Torna all'elenco per visualizzare l'elenco dei corsi con il numero di crediti modificato.
Per altre informazioni sulle query SQL non elaborate, vedere Query SQL non elaborate nel blog del team di Entity Framework.
senza rilevamento delle modifiche
Quando un contesto di database recupera le righe di database e crea oggetti entità che li rappresentano, per impostazione predefinita tiene traccia del fatto che le entità in memoria siano sincronizzate con ciò che si trova nel database. I dati in memoria svolgono la funzione di una cache e vengono usati per l'aggiornamento di un'entità. Questa memorizzazione nella cache spesso non è necessaria in un'applicazione Web poiché le istanze del contesto hanno spesso una durata breve (viene creata ed eliminata una nuova istanza per ogni richiesta) e il contesto che legge un'entità viene in genere eliminato prima che l'entità venga riutilizzata.
È possibile specificare se il contesto tiene traccia degli oggetti entità per una query usando il AsNoTracking
metodo . Gli scenari tipici in cui viene disabilitata la registrazione includono i seguenti:
- La query recupera un volume di dati di questo tipo che disattiva il rilevamento potrebbe migliorare notevolmente le prestazioni.
- Si vuole collegare un'entità per aggiornarla, ma in precedenza è stata recuperata la stessa entità per uno scopo diverso. Poiché l'entità viene già registrata dal contesto di database, non è possibile collegare l'entità che si vuole modificare. Un modo per evitare questo problema consiste nell'usare l'opzione
AsNoTracking
con la query precedente.
In questa sezione si implementerà la logica di business che illustra il secondo di questi scenari. In particolare, verrà applicata una regola business che indica che un insegnante non può essere l'amministratore di più di un reparto.
In DepartmentController.cs aggiungere un nuovo metodo che è possibile chiamare dai Edit
metodi e Create
per assicurarsi che nessun reparto abbia lo stesso amministratore:
private void ValidateOneAdministratorAssignmentPerInstructor(Department department)
{
if (department.PersonID != null)
{
var duplicateDepartment = db.Departments
.Include("Administrator")
.Where(d => d.PersonID == department.PersonID)
.FirstOrDefault();
if (duplicateDepartment != null && duplicateDepartment.DepartmentID != department.DepartmentID)
{
var errorMessage = String.Format(
"Instructor {0} {1} is already administrator of the {2} department.",
duplicateDepartment.Administrator.FirstMidName,
duplicateDepartment.Administrator.LastName,
duplicateDepartment.Name);
ModelState.AddModelError(string.Empty, errorMessage);
}
}
}
Aggiungere codice nel try
blocco del HttpPost
Edit
metodo per chiamare questo nuovo metodo se non sono presenti errori di convalida. Il try
blocco è ora simile all'esempio seguente:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(
[Bind(Include = "DepartmentID, Name, Budget, StartDate, RowVersion, PersonID")]
Department department)
{
try
{
if (ModelState.IsValid)
{
ValidateOneAdministratorAssignmentPerInstructor(department);
}
if (ModelState.IsValid)
{
db.Entry(department).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DbUpdateConcurrencyException ex)
{
var entry = ex.Entries.Single();
var clientValues = (Department)entry.Entity;
Eseguire la pagina Modifica reparto e provare a modificare l'amministratore di un reparto in un insegnante che è già l'amministratore di un reparto diverso. Viene visualizzato il messaggio di errore previsto:
Eseguire di nuovo la pagina Modifica reparto e questa volta modificare l'importo budget . Quando si fa clic su Salva, viene visualizzata una pagina di errore:
Il messaggio di errore di eccezione è "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
" Si è verificato a causa della sequenza di eventi seguente:
- Il
Edit
metodo chiama ilValidateOneAdministratorAssignmentPerInstructor
metodo , che recupera tutti i reparti che hanno Kim Abercrombie come amministratore. Ciò fa sì che il reparto inglese venga letto. Poiché si tratta del reparto da modificare, non viene segnalato alcun errore. In seguito a questa operazione di lettura, tuttavia, l'entità del reparto inglese letta dal database viene ora rilevata dal contesto del database. - Il
Edit
metodo tenta di impostare ilModified
flag sull'entità del reparto inglese creata dal gestore di associazione di modelli MVC, ma l'operazione ha esito negativo perché il contesto tiene già traccia di un'entità per il reparto inglese.
Una soluzione a questo problema consiste nel impedire al contesto di tenere traccia delle entità del reparto in memoria recuperate dalla query di convalida. Non c'è alcun svantaggio per farlo, perché non si aggiornerà questa entità o la si leggerà di nuovo in modo da trarre vantaggio dalla memorizzazione nella cache in memoria.
In DepartmentController.cs, nel ValidateOneAdministratorAssignmentPerInstructor
metodo specificare nessun rilevamento, come illustrato di seguito:
var duplicateDepartment = db.Departments
.Include("Administrator")
.Where(d => d.PersonID == department.PersonID)
.AsNoTracking()
.FirstOrDefault();
Ripetere il tentativo di modificare l'importo budget di un reparto. Questa volta che l'operazione ha esito positivo e il sito viene restituito come previsto nella pagina Indice reparti, che mostra il valore del budget modificato.
Esame delle query inviate al database
A volte può essere utile visualizzare le query SQL inviate al database. A tale scopo, è possibile esaminare una variabile di query nel debugger o chiamare il metodo della ToString
query. Per provare questa operazione, si esaminerà una query semplice e quindi si esaminerà cosa accade quando si aggiungono opzioni come caricamento eager, filtro e ordinamento.
In Controllers/CourseController sostituire il Index
metodo con il codice seguente:
public ViewResult Index()
{
var courses = unitOfWork.CourseRepository.Get();
return View(courses.ToList());
}
Impostare ora un punto di interruzione in GenericRepository.cs sulle return query.ToList();
istruzioni e return orderBy(query).ToList();
del Get
metodo . Eseguire il progetto in modalità di debug e selezionare la pagina Indice corso. Quando il codice raggiunge il punto di interruzione, esaminare la query
variabile. Viene visualizzata la query inviata a SQL Server. È una semplice Select
affermazione:
{SELECT
[Extent1].[CourseID] AS [CourseID],
[Extent1].[Title] AS [Title],
[Extent1].[Credits] AS [Credits],
[Extent1].[DepartmentID] AS [DepartmentID]
FROM [Course] AS [Extent1]}
Le query possono essere troppo lunghe da visualizzare nelle finestre di debug in Visual Studio. Per visualizzare l'intera query, è possibile copiare il valore della variabile e incollarlo in un editor di testo:
A questo punto si aggiungerà un elenco a discesa alla pagina Indice corso in modo che gli utenti possano filtrare per un determinato reparto. I corsi verranno ordinati in base al titolo e si specificherà il caricamento eager per la Department
proprietà di navigazione. In CourseController.cs sostituire il Index
metodo con il codice seguente:
public ActionResult Index(int? SelectedDepartment)
{
var departments = unitOfWork.DepartmentRepository.Get(
orderBy: q => q.OrderBy(d => d.Name));
ViewBag.SelectedDepartment = new SelectList(departments, "DepartmentID", "Name", SelectedDepartment);
int departmentID = SelectedDepartment.GetValueOrDefault();
return View(unitOfWork.CourseRepository.Get(
filter: d => !SelectedDepartment.HasValue || d.DepartmentID == departmentID,
orderBy: q => q.OrderBy(d => d.CourseID),
includeProperties: "Department"));
}
Il metodo riceve il valore selezionato dell'elenco a discesa nel SelectedDepartment
parametro . Se non è selezionata alcuna opzione, questo parametro sarà Null.
Una SelectList
raccolta contenente tutti i reparti viene passata alla visualizzazione per l'elenco a discesa. I parametri passati al SelectList
costruttore specificano il nome del campo valore, il nome del campo di testo e l'elemento selezionato.
Per il Get
metodo del Course
repository, il codice specifica un'espressione di filtro, un ordinamento e il caricamento eager per la proprietà di Department
navigazione. L'espressione di filtro restituisce true
sempre se nell'elenco a discesa non è selezionato nulla, SelectedDepartment
ovvero null.
In Views\Course\Index.cshtml, immediatamente prima del tag di apertura table
, aggiungere il codice seguente per creare l'elenco a discesa e un pulsante di invio:
@using (Html.BeginForm())
{
<p>Select Department: @Html.DropDownList("SelectedDepartment","All")
<input type="submit" value="Filter" /></p>
}
Con i punti di interruzione ancora impostati nella GenericRepository
classe , eseguire la pagina Indice corso. Continuare con le prime due volte in cui il codice raggiunge un punto di interruzione, in modo che la pagina venga visualizzata nel browser. Selezionare un reparto dall'elenco a discesa e fare clic su Filtro:
Questa volta il primo punto di interruzione sarà per la query dei reparti per l'elenco a discesa. Ignorare questa variabile e visualizzare la query
variabile al successivo raggiungimento del punto di interruzione per visualizzare l'aspetto della Course
query. Verrà visualizzato un aspetto simile al seguente:
{SELECT
[Extent1].[CourseID] AS [CourseID],
[Extent1].[Title] AS [Title],
[Extent1].[Credits] AS [Credits],
[Extent1].[DepartmentID] AS [DepartmentID],
[Extent2].[DepartmentID] AS [DepartmentID1],
[Extent2].[Name] AS [Name],
[Extent2].[Budget] AS [Budget],
[Extent2].[StartDate] AS [StartDate],
[Extent2].[PersonID] AS [PersonID],
[Extent2].[Timestamp] AS [Timestamp]
FROM [Course] AS [Extent1]
INNER JOIN [Department] AS [Extent2] ON [Extent1].[DepartmentID] = [Extent2].[DepartmentID]
WHERE (@p__linq__0 IS NULL) OR ([Extent1].[DepartmentID] = @p__linq__1)}
È possibile notare che la query è ora una JOIN
query che carica Department
i dati insieme ai Course
dati e che include una WHERE
clausola .
Uso delle classi proxy
Quando Entity Framework crea istanze di entità, ad esempio quando si esegue una query, spesso le crea come istanze di un tipo derivato generato dinamicamente che funge da proxy per l'entità. Questo proxy esegue l'override di alcune proprietà virtuali dell'entità per inserire hook per l'esecuzione automatica di azioni quando si accede alla proprietà. Ad esempio, questo meccanismo viene usato per supportare il caricamento differita delle relazioni.
Nella maggior parte dei casi non è necessario conoscere questo uso di proxy, ma esistono eccezioni:
- In alcuni scenari potrebbe essere necessario impedire a Entity Framework di creare istanze proxy. Ad esempio, la serializzazione di istanze non proxy potrebbe essere più efficiente rispetto alla serializzazione delle istanze proxy.
- Quando si crea un'istanza di una classe di entità usando l'operatore , non si ottiene un'istanza
new
del proxy. Ciò significa che non si ottengono funzionalità come il caricamento differita e il rilevamento automatico delle modifiche. Questo è in genere ok; in genere non è necessario eseguire il caricamento differita, perché si sta creando una nuova entità che non si trova nel database e in genere non è necessario eseguire il rilevamento delle modifiche se si contrassegna in modo esplicito l'entità comeAdded
. Tuttavia, se è necessario il caricamento differita ed è necessario il rilevamento delle modifiche, è possibile creare nuove istanze di entità con proxy usando ilCreate
metodo dellaDbSet
classe . - Potrebbe essere necessario ottenere un tipo di entità effettivo da un tipo proxy. È possibile usare il
GetObjectType
metodo dellaObjectContext
classe per ottenere il tipo di entità effettivo di un'istanza del tipo proxy.
Per altre informazioni, vedere Uso dei proxy nel blog del team di Entity Framework.
Disabilitazione del rilevamento automatico delle modifiche
Entity Framework determina come è stata modificata un'entità (e di conseguenza gli aggiornamenti da inviare al database) confrontando i valori correnti di un'entità con i valori originali. I valori originali vengono archiviati quando l'entità è stata sottoposta a query o associata. I metodi che causano il rilevamento automatico delle modifiche includono:
DbSet.Find
DbSet.Local
DbSet.Remove
DbSet.Add
DbSet.Attach
DbContext.SaveChanges
DbContext.GetValidationErrors
DbContext.Entry
DbChangeTracker.Entries
Se si rileva un numero elevato di entità e si chiama uno di questi metodi più volte in un ciclo, è possibile ottenere miglioramenti significativi delle prestazioni disattivando temporaneamente il rilevamento automatico delle modifiche usando la proprietà AutoDetectChangesEnabled . Per altre informazioni, vedere Rilevamento automatico delle modifiche.
Disabilitazione della convalida durante il salvataggio delle modifiche
Quando si chiama il SaveChanges
metodo, per impostazione predefinita Entity Framework convalida i dati in tutte le proprietà di tutte le entità modificate prima di aggiornare il database. Se è stato aggiornato un numero elevato di entità e i dati sono già stati convalidati, questo lavoro non è necessario ed è possibile che il processo di salvataggio delle modifiche richiede meno tempo disattivando temporaneamente la convalida. A tale scopo, è possibile usare la proprietà ValidateOnSaveEnabled . Per ulteriori informazioni, consultare Convalida.
Riepilogo
Questa serie di esercitazioni sull'uso di Entity Framework in un'applicazione MVC ASP.NET completa questa serie di esercitazioni. I collegamenti ad altre risorse di Entity Framework sono disponibili nella mappa del contenuto di accesso ai dati ASP.NET.
Per altre informazioni su come distribuire l'applicazione Web dopo averlo compilato, vedere ASP.NET Deployment Content Map in MSDN Library.
Per informazioni su altri argomenti correlati a MVC, ad esempio l'autenticazione e l'autorizzazione, vedere Le risorse consigliate per MVC.
Riconoscimenti
- Tom Dykstra ha scritto la versione originale di questa esercitazione ed è un senior programming writer del team di contenuto Piattaforma Web Microsoft e tools.
- Rick Anderson (twitter @RickAndMSFT) ha creato questa esercitazione e ha eseguito la maggior parte del lavoro aggiornandolo per EF 5 e MVC 4. Rick è un senior programming writer per Microsoft incentrato su Azure e MVC.
- Rowan Miller e altri membri del team di Entity Framework hanno assistito con revisioni del codice e hanno contribuito a eseguire il debug di molti problemi con le migrazioni che si sono verificati durante l'aggiornamento dell'esercitazione per EF 5.
VB
Quando l'esercitazione è stata originariamente prodotta, sono state fornite versioni C# e VB del progetto di download completato. Con questo aggiornamento viene fornito un progetto scaricabile C# per ogni capitolo per semplificare l'avvio ovunque nella serie, ma a causa di limitazioni temporali e altre priorità non è stato fatto per VB. Se si compila un progetto VB usando queste esercitazioni e si è disposti a condividerlo con altri utenti, segnalarlo.
Errori e soluzioni alternative
Impossibile creare/copiare shadow
Messaggio di errore:
Impossibile creare/shadow copy 'DotNetOpenAuth.OpenId' quando il file esiste già.
Soluzione:
Attendere alcuni secondi e aggiornare la pagina.
Update-Database non riconosciuto
Messaggio di errore:
Il termine 'Update-Database' non viene riconosciuto come nome di un cmdlet, di una funzione, di un file di script o di un programma eseguibile. Verificare l'ortografia del nome, che il percorso sia incluso e corretto, quindi riprovare.Dal Update-Database
comando in PMC.
Soluzione:
Uscire da Visual Studio. Riaprire il progetto e riprovare.
Convalida non riuscita
Messaggio di errore:
Convalida non riuscita per una o più entità. Per altri dettagli, vedere la proprietà 'EntityValidationErrors'. Dal Update-Database
comando in PMC.
Soluzione:
Una causa di questo problema è costituita dagli errori di convalida durante l'esecuzione del Seed
metodo. Vedere Seeding and Debugging Entity Framework (EF) DBs (Seeding and Debugging Entity Framework) (Seeding and Debugging Entity Framework (EF) DBs (Seeding and Debugging Entity Framework) (Seeding and Debugging Entity Framework (EF) DBs ( Seed
Seeding and Debugging Entity Framework
Errore HTTP 500.19
Messaggio di errore:
Errore HTTP 500.19 - Errore interno del server
Impossibile accedere alla pagina richiesta perché i dati di configurazione correlati per la pagina non sono validi.
Soluzione:
Un modo per ottenere questo errore consiste nell'avere più copie della soluzione, ognuna usando lo stesso numero di porta. In genere è possibile risolvere questo problema chiudendo tutte le istanze di Visual Studio, quindi riavviando il progetto su cui si lavora. In caso contrario, provare a modificare il numero di porta. Fare clic con il pulsante destro del mouse sul file di progetto e quindi scegliere proprietà. Selezionare la scheda Web e quindi modificare il numero di porta nella casella di testo Url progetto.
Errore di individuazione dell'istanza di SQL Server
Messaggio di errore:
Si è verificato un errore di rete o specifico dell'istanza mentre veniva stabilita la connessione a SQL Server. Il server non è stato trovato o non è accessibile. Verificare che il nome dell'istanza sia corretto e che il server sia configurato in modo da consentire connessioni remote. (provider: interfacce di rete SQL, errore: 26 - Errore nell'individuazione del server/dell'istanza specificata)
Soluzione:
Controllare stringa di connessione. Se il database è stato eliminato manualmente, modificare il nome del database nella stringa di costruzione.