EF7 - Cómo obtener valores de DbSet antes del cambio

asp.net c# entity-framework entity-framework-core linq

Pregunta

Intento obtener el valor de entidad que se almacenó en DbSet antes de que fuera modificado por el código y antes de que se guardara. Sin embargo, cuando trato de obtenerlo con LINQ Single , recibo el valor cambiado. Estoy usando EF7.

Aquí está el código:

DbSet<Entity> dbSet = Context.dbSet;
Entity ent = dbSet.Single(x => x.Id == id);
ent.FirstName = "New name";
Entity entityBeforeChange = dbSet.Single(x => x.Id == id);  //here I want to get entity with old values, if that's important I just need to read it without modifying this instance

Context.SaveChanges();

Espero haber sido lo suficientemente claro y pueda obtener ayuda

Respuesta aceptada

Puedes Detach una entidad del contexto. Tenga en cuenta que tendrá que extraerlo del contexto antes de actualizar la otra entidad adjunta.

DbSet<Entity> dbSet = Context.dbSet;
Entity ent = dbSet.Single(x => x.Id == id);
Entity entityBeforeChange = dbSet.Single(x => x.Id == id); 
Context.Entry(entityBeforeChange).State = EntityState.Detached; // severs the connection to the Context
ent.FirstName = "New name";

Context.SaveChanges();

Respuesta experta

Aquí hay un código que uso de mi biblioteca de auditoría.

EF7

using (var ctx = new TestContext())
{
    Entity ent = entity.Single(x => x.Id == id);
    entity.FirstName = "New name";

    context.ChangeTracker.DetectChanges();

    // Find your entry or get all changed entries
    var changes = context.ChangeTracker.Entries().Where(x => x.State == EntityState.Modified);

    foreach (var objectStateEntry in changes)
    {
        AuditEntityModified(audit, objectStateEntry, auditState);
    }
}

public static void AuditEntityModified(Audit audit, AuditEntry entry, EntityEntry objectStateEntry)
{
    foreach (var propertyEntry in objectStateEntry.Metadata.GetProperties())
    {
        var property = objectStateEntry.Property(propertyEntry.Name);

        if (entry.Parent.CurrentOrDefaultConfiguration.IsAudited(entry.ObjectStateEntry, propertyEntry.Name))
        {
            entry.Properties.Add(new AuditEntryProperty(entry, propertyEntry.Name, property.OriginalValue, property.CurrentValue));
        }
    }
}

EF6

using (var ctx = new TestContext())
{
    Entity ent = entity.Single(x => x.Id == id);
    entity.FirstName = "New name";

    context.ChangeTracker.DetectChanges();

    // Find your entry or get all changed entries
    var changes = context.ChangeTracker.Entries().Where(x => x.State == EntityState.Modified);

    foreach (var objectStateEntry in changes)
    {
        AuditEntityModified(audit, objectStateEntry, auditState);
    }
}

public static void AuditEntityModified(Audit audit, AuditEntry entry, EntityEntry objectStateEntry)
{
    foreach (var propertyEntry in objectStateEntry.Metadata.GetProperties())
    {
        var property = objectStateEntry.Property(propertyEntry.Name);

        if (entry.Parent.CurrentOrDefaultConfiguration.IsAudited(entry.ObjectStateEntry, propertyEntry.Name))
        {
            entry.Properties.Add(new AuditEntryProperty(entry, propertyEntry.Name, property.OriginalValue, property.CurrentValue));
        }
    }
}

Edición: el código fuente completo se puede encontrar en mi repositorio de GitHub: https://github.com/zzzprojects/EntityFramework-Plus

Sitio web de la biblioteca: http://entityframework-plus.net/




Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué