0

私は現在、エンティティの個々のプロパティへの変更をログに記録する必要があるプロジェクトに取り組んでいます。エンティティの多くは、ルックアップ値の型と 1 対多の関係を持っており、これが変更された場合、これまでのところ、「1」が「2」に変更されたことを追跡できます。私が達成しようとしているのは、数値をより読みやすい値に変換することです。

私は動作すると思っていた以下のコードを持っていますが、動作しません:(

namespace DomainClasses
{
    public interface IAuditDescribable
    {
        String GetAuditDescription();
    }
    public abstract class BaseEntity
    {
        public Int32 Id { get; set; }
    }
    public class Car : BaseEntity
    {
        public String Vrn { get; set; }
        public Int32? TransmissionId { get; set; }
        public virtual Transmission Transmission { get; set; }
    }
    public class Transmission : BaseEntity, IAuditDescribable
    {
        public String Name { get; set; }
        public String GetAuditDescription()
        {
            return Name;
        }
    }
}


namespace AuditTrailTwo
{
    public class AuditContext : DbContext
    {    
        public DbSet<Car> Cars { get; set; }
        public DbSet<Transmission> Transmissions { get; set; }

        public override int SaveChanges()
        {
            ChangeTracker.DetectChanges();

            var octx = ((IObjectContextAdapter)this).ObjectContext;
            var changes = octx.ObjectStateManager.GetObjectStateEntries(EntityState.Modified);

            foreach (var change in changes)
            {
                var changedProperties = change.GetModifiedProperties();
                var associationSets = change.EntitySet.EntityContainer.AssociationSets;

                foreach (var changedProperty in changedProperties)
                {
                    CurrentValueRecord current = change.CurrentValues;
                    var newValue = current.GetValue(
                        current.GetOrdinal(changedProperty));

                    DbDataRecord original = change.OriginalValues;
                    var oldValue = original.GetValue(
                        original.GetOrdinal(changedProperty));

                    var aSet = associationSets
                        .Where(x => x.ElementType.IsForeignKey)
                        .FirstOrDefault(x => x.ElementType.Constraint.ToProperties[0].Name == changedProperty);

                    if (aSet != null)
                    {
                        var targetEnd = aSet.AssociationSetEnds.GetValue(aSet.Name+"_Target", true);


                        //This type is always null because the 'FullName' returns: 'AuditTrailTwo.Transmission'
                        //and not 'DomainClasses.Transmission' as I was expecting.
                        var type = Type.GetType(targetEnd.EntitySet.ElementType.FullName);

                        if (type != null)
                        {
                            var typeSet = Set(type);

                            var newEntry = typeSet.Find(newValue) as IAuditDescribable;
                            var newEntryValue = newEntry.GetAuditDescription();

                            var oldEntry = typeSet.Find(oldValue) as IAuditDescribable;
                            var oldEntryValue = oldEntry.GetAuditDescription(); 
                        }
                    }
                }
            }
            return base.SaveChanges();
        }
    }
}

エンティティ フレームワークを使用した監査について説明している多くの投稿を見てきましたが、これまでのところ、私がやろうとしていることを達成する方法は見つかりませんでした。単に何かを見落としているからだと思います。

どんな助けでも大歓迎です。

4

1 に答える 1

0

アスペクト指向プログラミングを使用して、プロパティが変更されたときに処理できます。 http://www.postsharp.net/

于 2014-01-10T01:51:05.920 に答える