Entity Framework: ¿por qué establecer explícitamente el estado de la entidad como modificado?

Resuelto SeeNoWeevil asked hace 13 años • 2 respuestas

La documentación oficial dice que para modificar una entidad recupero un objeto DbEntityEntry y trabajo con las funciones de propiedad o configuro su estado como modificado. Utiliza el siguiente ejemplo.

Department dpt = context.Departments.FirstOrDefault();
DbEntityEntry entry = context.Entry(dpt);
entry.State = EntityState.Modified;

No entiendo el propósito de la segunda y tercera declaración. Si solicito el marco para una entidad como lo hace la primera declaración y luego modifico POCO como en

dpt.Name = "Blah"

Si luego le pido a EF que SaveChanges(), la entidad tiene un estado MODIFICADO (supongo que mediante seguimiento de instantáneas, esto no es un proxy) y los cambios persisten sin la necesidad de configurar manualmente el estado. ¿Me estoy perdiendo de algo?

SeeNoWeevil avatar Aug 18 '11 17:08 SeeNoWeevil
Aceptado

En su escenario, de hecho, no es necesario establecer el estado. El propósito del seguimiento de cambios es encontrar que ha cambiado un valor en la entidad adjunta y lo ha puesto en estado modificado. Configurar el estado manualmente es importante en el caso de entidades separadas (entidades cargadas sin seguimiento de cambios o creadas fuera del contexto actual).

Ladislav Mrnka avatar Aug 18 '2011 10:08 Ladislav Mrnka

Como se dijo, en un escenario con entidades desconectadas puede resultar útil establecer el estado de una entidad en Modified. Guarda un viaje de ida y vuelta a la base de datos si simplemente adjunta la entidad desconectada, en lugar de buscar la entidad de la base de datos y modificarla y guardarla.

Pero puede haber muy buenas razones para no establecer el estado Modified(y estoy seguro de que Ladislav estaba al tanto de esto, pero aun así me gustaría señalarlas aquí).

  1. Se actualizarán todos los campos del registro, no solo los cambios. Hay muchos sistemas en los que se auditan las actualizaciones. La actualización de todos los campos provocará una gran cantidad de desorden o requerirá que el mecanismo de auditoría filtre los cambios falsos.

  2. Concurrencia optimista. Dado que todos los campos están actualizados, esto puede causar más conflictos de los necesarios. Si dos usuarios actualizan los mismos registros simultáneamente pero no los mismos campos, no tiene por qué haber un conflicto. Pero si siempre actualizan todos los campos, el último usuario siempre intentará escribir datos obsoletos. En el mejor de los casos, esto provocará una excepción de simultaneidad optimista o, en el peor de los casos, una pérdida de datos.

  3. Actualizaciones inútiles. La entidad se marca como modificada, pase lo que pase. Las entidades sin cambios también activarán una actualización. Esto puede ocurrir fácilmente si las ventanas de edición se pueden abrir para ver detalles y cerrar con OK.

Entonces es un buen equilibrio. Reduzca los viajes de ida y vuelta o reduzca la redundancia.

De todos modos, una alternativa para establecer el estado Modifiedes (usando DbContextAPI):

void UpdateDepartment(Department department)
{
    var dpt = context.Departments.Find(department.Id);
    context.Entry(dpt).CurrentValues.SetValues(department);
    context.SaveChanges();
}

CurrentValues.SetValuesmarca propiedades individuales como Modified.

O adjunte una entidad desconectada y marque las propiedades individuales Modifiedmanualmente:

context.Entry(dpt).State = System.Data.Entity.EntityState.Unchanged;
context.Entry(dpt).Property(d => d.Name).IsModified = true;
Gert Arnold avatar Jun 13 '2015 22:06 Gert Arnold