with update setvalues modified framework currentvalues attach entity-framework entity-framework-5 dbcontext

entity-framework - update - save entity framework c#



DbContext AutoDetectChangesEnabled establecido en detección de cambios falsos (3)

Establecer AutoDetectChangesEnabled en false no deshabilita el seguimiento de cambios. (Eso es lo que AsNoTracking() método de extensión AsNoTracking() ). Simplemente deshabilita la llamada automática de DetectChanges que de otro modo se produciría en muchos métodos de la API DbContext .

Pero DetectChanges no es el único método que participa en el seguimiento de cambios. Sin embargo, si no lo llama manualmente en los lugares correctos donde se necesita, los estados de las entidades rastreados están incompletos o son incorrectos, lo que lleva a que los datos guarden incorrectamente.

En su caso, se espera el estado Added en la primera parte de su method , incluso con AutoDetectChangesEnabled establecido en false porque solo llama a db.Projects.Add(p) . (La línea falta en su código por cierto, pero supongo que es solo un error de copiar y pegar). Llamar a un método desde la API DbContext rastrea los cambios correctamente y los estados en el rastreador serán correctos si el estado era correcto antes de la llamada a Add

O en otras palabras: Llamar a un método API no convierte un estado correcto en un estado incorrecto. Pero: si AutoDetectChangesEnabled es false , tampoco convertirá un estado incorrecto en un estado correcto, que sería el caso si AutoDetectChangesEnabled es true .

Sin embargo, en la segunda parte de su method solo está cambiando un valor de propiedad de POCO. Después de este punto, el estado del rastreador de cambios es incorrecto ( Unchanged ) y sin una llamada a DetectChanges (manualmente o si AutoDetectChangesEnabled es true , automáticamente en ChangeTracker.Entries o SaveChanges ) nunca se ajustará. El efecto es que el valor de la propiedad modificada no se guarda en la base de datos.

En la última sección que menciona el estado Unchanged me estoy refiriendo a mi propia prueba (y también a lo que esperaría). No sé y no puedo reproducir por qué tiene el estado Modified .

Lo siento, si esto suena un poco confuso. Arthur Vickers puede explicarlo mejor.

Encuentro que la detección automática de cambios y el comportamiento al deshabilitarla son bastante difíciles de entender y de dominar, y generalmente no toco el valor predeterminado ( AutoDetectChangesEnabled = true ) para los cambios rastreados que son más complejos que los más simples (como las entidades de adición masiva en un bucle, etc.).

Estoy un poco perplejo. Por lo que he leído, configurar DbContext.AutoDetectChangesEnabled en false debería deshabilitar el seguimiento de cambios que requiere que uno llame a DbContext.DetectChanges para identificar los cambios que se enviarán a la base de datos.

Sin embargo, de mis registros a continuación se desprende que los cambios están siendo registrados por dbContexts change tracker, incluso con la configuración establecida en falso.

¿Me estoy perdiendo de algo?

Versión de Entity Framework: 5.0.0.0

Clase DbContext

public class ProjectContext : DbContext { public DbSet<Project> Projects {get;set;} }

Clase de controlador

private ProjectContext db = new ProjectContext(); public method(){ Project p = new Project("uniqueName"); db.Configuration.AutoDetectChangesEnabled = false; db.Projects.Add(p); DebugChangeTracker(); db.SaveChanges(); db.Projects.First().ProjectName = "a differentName!"; DebugChangeTracker(); db.SaveChanges(); }

Método de registro

private void DebugChangeTracker() { var path = "C://mypath//"; path = path + Util.GetMsSinceEpoch().ToString() + "changeTracker.log"; using (StreamWriter sw = new StreamWriter(path)) { var changeTracker = db.ChangeTracker; var entries = changeTracker.Entries(); foreach (var x in entries) { var name = x.Entity.ToString(); var state = x.State; sw.WriteLine(""); sw.WriteLine("***Entity Name: " + name + "is in a state of " + state); var currentValues = x.CurrentValues; sw.WriteLine("***CurrentValues***"); PrintPropertyValues(currentValues,sw); if (state != EntityState.Added) { sw.WriteLine("***Original Values***"); PrintPropertyValues(x.OriginalValues,sw); } } } }

Primer registro

***Entity Name: Models.Projectis in a state of Added ***CurrentValues*** ProjectId:0 ProjectName:uniqueName

Segundo registro

***Entity Name: Models.Projectis in a state of Modified ***CurrentValues*** ProjectId:1 ProjectName:uniqueName ***Original Values*** ProjectId:1 ProjectName:a differentName!


Si alguien está buscando AutoDetectChangesEnabled en Entity Framework Core, puede encontrarlo en ChangeTracker en ChangeTracker de Configuration

Uso como:

context.ChangeTracker.AutoDetectChangesEnabled = false; //Do something here context.PriceRecords.Add(newPriceRecord); context.ChangeTracker.AutoDetectChangesEnabled = true;


según el artículo de Entity Framework Automatic Detect Changes

ellos dijeron:

puede obtener mejoras de rendimiento significativas apagándolo en some cases

mira este ejemplo de ese artículo

using (var context = new BloggingContext()) { try { context.Configuration.AutoDetectChangesEnabled = false; // Make many calls in a loop foreach (var blog in aLotOfBlogs) { context.Blogs.Add(blog); } } finally { context.Configuration.AutoDetectChangesEnabled = true; } }

Este código evita llamadas innecesarias a DetectChanges que se hubieran producido al llamar a los métodos DbSet.Add y SaveChanges .