원래 값 표시 Entity Framework 7

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

문제

추가, 삭제 및 수정 된 트랙 감사 테이블이 있습니다. 여러 가지 이유로 데이터베이스 트리거를 사용하는 대신 Entity Framework 내부를 추적하지만 실제로 프로세스 계정을 사용하고 실제로 해당 레코드를 변경 한 사용자를 추적하려고합니다.

나는 EF 5에서이 작업을했고 & EF6에서도 잘 작동했는지 기억이 안납니다. 어느 쪽이든 나는 EF 7이 원래의 가치를 포착하려고 애쓰는 가장 힘든시기를 보내고 있습니다.

내가 시계에있을 때 비공개 멤버의 원본 가치를 볼 수 있다는 것을 알았습니다. 그래서 내 머리 속에서 어딘가에 존재해야한다는 것을 알았습니다.

궁극적으로 이것은 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()
         }
         );
      }
 }

내가 얻는 오류는 EntityEntry가 OriginalValues에 대한 디비전을 포함하지 않는다는 것입니다. 나는 머리카락을 뽑아 낼 것입니다 ... EF 7을 사용하여 수정 된 객체에서 원본 값을 얻으려면 어떻게해야합니까?

수락 된 답변

// 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}");
}

인기 답변

또 다른 옵션은 여전히 OriginalValues를 사용하는 것이지만 PropertyNames 대신 Properties를 사용하십시오. 이렇게하면 foreach 루프 프로세스 유형이 Microsoft.EntityFrameworkCore.Metadata.IProperty가 됩니다. GetValues 메서드에는 IProperty 를 허용하는 오버로드가 있으므로 해당 코드에 대한 변경이 필요하지 않지만 ColumnName 할당을 propertyName 에서 property 로 변경해야 합니다 . 이름 .

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()
        });
    }
}



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.