元の値を表示する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()
        });
    }
}


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ