Mostrar valores originales Entity Framework 7

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

Pregunta

Tengo una tabla de auditoría que realiza un seguimiento de agregados, eliminados y modificados. Rastreo esto dentro de Entity Framework en lugar de usar un activador de base de datos por múltiples razones, pero en realidad porque usamos una Cuenta de Proceso y quiero rastrear qué usuario realizó físicamente ese cambio en ese registro.

Hice esto trabajando con EF 5 y no puedo recordar que podría haberlo hecho también en EF6. De cualquier manera, estoy teniendo dificultades para que EF 7 intente capturar los valores originales.

Noté que cuando estoy en el reloj, puedo ver Valores originales dentro de los miembros no públicos, por lo que en mi cabeza sé que tiene que existir en algún lugar.

En última instancia, esto funciona dentro de las versiones anteriores de EF:

EntityEntry dbEntry; //this is actually passed in a different area just showing as an example.

foreach (string propertyName in dbEntry.OriginalValues.PropertyNames)
{
    // For updates, we only want to capture the columns that actually changed
    if (!object.Equals(dbEntry.OriginalValues.GetValue<object>(propertyName), dbEntry.CurrentValues.GetValue<object>(propertyName)))
    {
        result.Add(new TableChange()
        {
            AuditLogID = Guid.NewGuid(),
            UserID = userId,
            EventDateUTC = changeTime,
            EventType = "M",    // Modified
            TableName = tableName,
            RecordID = dbEntry.OriginalValues.GetValue<object>(keyName).ToString(),
            ColumnName = propertyName,
            OriginalValue = dbEntry.OriginalValues.GetValue<object>(propertyName) == null ? null : dbEntry.OriginalValues.GetValue<object>(propertyName).ToString(),
            NewValue = dbEntry.CurrentValues.GetValue<object>(propertyName) == null ? null : dbEntry.CurrentValues.GetValue<object>(propertyName).ToString()
         }
         );
      }
 }

El error que recibo es que EntityEntry no contiene una definición para OriginalValues. Voy a quitarme el pelo ... ¿Cómo obtengo los valores originales de un objeto modificado con EF 7?

Respuesta aceptada

// using System.Reflection;
foreach (var property in dbEntry.Entity.GetType().GetTypeInfo().DeclaredProperties)
{
    var originalValue = dbEntry.Property(property.Name).OriginalValue;
    var currentValue = dbEntry.Property(property.Name).CurrentValue;
    Console.WriteLine($"{property.Name}: Original: {originalValue}, Current: {currentValue}");
}

Respuesta popular

Otra opción es seguir usando los valores originales , pero en lugar de los nombres de propiedad , use las propiedades . Esto hará que los tipos de proceso de bucle foreach de Microsoft.EntityFrameworkCore.Metadata.IProperty . El método GetValues tiene una sobrecarga que acepta propiedad IP , por lo que no es necesario realizar cambios en el código de esas llamadas, pero deberá cambiar la asignación de Nombre de columna de propertyName a property . Nombre

foreach (var property in entityEntry.OriginalValues.Properties)
{
    if (!object.Equals(entityEntry.OriginalValues.GetValue<object>(property), 
        entityEntry.CurrentValues.GetValue<object>(property)))
    {
        result.Add(
            new AuditLog()
            {
                UserId = userId,
                EventDate = changeTime,
                EventType = "M",
                TableName = tableName,
                RecordId = entityEntry.OriginalValues.GetValue<object>(keyName).ToString(),
                ColumnName = property.Name,
                OriginalValue =
                    entityEntry.OriginalValues.GetValue<object>(property) == null
                    ? null
                    : entityEntry.OriginalValues.GetValue<object>(property).ToString(),
                NewValue = 
                    entityEntry.CurrentValues.GetValue<object>(property) == null
                    ? null
                    : entityEntry.CurrentValues.GetValue<object>(property).ToString()
        });
    }
}



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é