Entity Framework: rilevamento delle modifiche
Entity Framework fornisce la capacità di tenere traccia delle modifiche apportate alle entità e alle loro relazioni, quindi gli aggiornamenti corretti vengono effettuati sul database quando viene chiamato il metodo di contesto SaveChanges. Questa è una caratteristica fondamentale di Entity Framework.
Il rilevamento delle modifiche tiene traccia delle modifiche durante l'aggiunta di nuovi record alla raccolta di entità, la modifica o la rimozione di entità esistenti.
Quindi tutte le modifiche vengono mantenute dal livello DbContext.
Queste modifiche alla traccia vengono perse se non vengono salvate prima che l'oggetto DbContext venga eliminato.
La classe DbChangeTracker fornisce tutte le informazioni sulle entità correnti tracciate dal contesto.
Per tenere traccia di qualsiasi entità in base al contesto, deve avere la proprietà della chiave primaria.
In Entity Framework, il rilevamento delle modifiche è abilitato per impostazione predefinita. È inoltre possibile disabilitare il rilevamento delle modifiche impostando la proprietà AutoDetectChangesEnabled di DbContext su false. Se questa proprietà è impostata su true, Entity Framework mantiene lo stato delle entità.
using (var context = new UniContextEntities()) {
context.Configuration.AutoDetectChangesEnabled = true;
}
Diamo uno sguardo al seguente esempio in cui gli studenti e le loro iscrizioni vengono recuperati dal database.
class Program {
static void Main(string[] args) {
using (var context = new UniContextEntities()) {
context.Configuration.AutoDetectChangesEnabled = true;
Console.WriteLine("Retrieve Student");
var student = (from s in context.Students where s.FirstMidName ==
"Ali" select s).FirstOrDefault<Student>();
string name = student.FirstMidName + " " + student.LastName;
Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);
Console.WriteLine();
Console.WriteLine("Retrieve all related enrollments");
foreach (var enrollment in student.Enrollments) {
Console.WriteLine("Enrollment ID: {0}, Course ID: {1}",
enrollment.EnrollmentID, enrollment.CourseID);
}
Console.WriteLine();
Console.WriteLine("Context tracking changes of {0} entity.",
context.ChangeTracker.Entries().Count());
var entries = context.ChangeTracker.Entries();
foreach (var entry in entries) {
Console.WriteLine("Entity Name: {0}", entry.Entity.GetType().Name);
Console.WriteLine("Status: {0}", entry.State);
}
Console.ReadKey();
}
}
}
Quando l'esempio precedente viene compilato ed eseguito, riceverai il seguente output.
Retrieve Student
ID: 1, Name: Ali Alexander
Retrieve all related enrollments
Enrollment ID: 1, Course ID: 1050
Enrollment ID: 2, Course ID: 4022
Enrollment ID: 3, Course ID: 4041
Context tracking changes of 4 entity.
Entity Name: Student
Status: Unchanged
Entity Name: Enrollment
Status: Unchanged
Entity Name: Enrollment
Status: Unchanged
Entity Name: Enrollment
Status: Unchanged
Puoi vedere che tutti i dati vengono recuperati solo dal database, ecco perché lo stato è invariato per tutte le entità.
Diamo ora un'occhiata a un altro semplice esempio in cui aggiungeremo un'altra iscrizione ed elimineremo uno studente dal database. Di seguito è riportato il codice in cui viene aggiunta la nuova iscrizione e uno studente viene eliminato.
class Program {
static void Main(string[] args) {
using (var context = new UniContextEntities()) {
context.Configuration.AutoDetectChangesEnabled = true;
Enrollment enr = new Enrollment() {
StudentID = 1, CourseID = 3141
};
Console.WriteLine("Adding New Enrollment");
context.Enrollments.Add(enr);
Console.WriteLine("Delete Student");
var student = (from s in context.Students where s.ID ==
23 select s).SingleOrDefault<Student>();
context.Students.Remove(student);
Console.WriteLine("");
Console.WriteLine("Context tracking changes of {0} entity.",
context.ChangeTracker.Entries().Count());
var entries = context.ChangeTracker.Entries();
foreach (var entry in entries) {
Console.WriteLine("Entity Name: {0}", entry.Entity.GetType().Name);
Console.WriteLine("Status: {0}", entry.State);
}
Console.ReadKey();
}
}
}
Quando l'esempio precedente viene compilato ed eseguito, riceverai il seguente output.
Adding New Enrollment
Delete Student
Context tracking changes of 2 entity.
Entity Name: Enrollment
Status: Added
Entity Name: Student
Status: Deleted
È ora possibile vedere che lo stato dell'entità di iscrizione è impostato su aggiunto e lo stato dell'entità studente viene eliminato, perché è stata aggiunta una nuova iscrizione e uno studente è stato rimosso dal database.
Si consiglia di eseguire l'esempio precedente in modo graduale per una migliore comprensione.