2013-11-26 21 views
2

我使用实体框架4.1,我有我的DbContext覆盖SaveChanges审计属性更改。代码从'GetEntryValueInString'返回空值。它的因果“如果(entry.Entity是EntityObject)”这种情况在所有情况下都失败了。如果我评论条件我有另一个问题像CurrentValues和OriginalValues变得相同。DbDataRecord - entry.CurrentValues和entry.originalValues是相同的

namespace mymodel 
{ 
using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Data.Entity; 
using System.Data.Entity.Infrastructure; 
using System.Data.Objects; 
using System.Data.Objects.DataClasses; 
using System.IO; 
using System.Reflection; 
using System.Runtime.Serialization; 
using System.Xml; 
using System.Xml.Linq; 
using System.Xml.Serialization; 

public partial class DbEntities : DbContext 
{ 
    public DbEntities() 
     : base("name=DbEntities ") 
    { 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     throw new UnintentionalCodeFirstException(); 
    } 

    public DbSet<DBAudit> DBAudits { get; set; } 

    public string UserName { get; set; } 
    List<DBAudit> auditTrailList = new List<DBAudit>(); 

    public enum AuditActions 
    { 
     I, 
     U, 
     D 
    } 

    public override int SaveChanges() 
    { 

     ChangeTracker.DetectChanges(); // Important! 

     ObjectContext ctx = ((IObjectContextAdapter)this).ObjectContext; 


     IEnumerable<ObjectStateEntry> changes = ctx.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified); 
     foreach (ObjectStateEntry stateEntryEntity in changes) 
     { 
      if (!stateEntryEntity.IsRelationship && 
        stateEntryEntity.Entity != null && 
         !(stateEntryEntity.Entity is DBAudit)) 
      {//is a normal entry, not a relationship 
       DBAudit audit = this.AuditTrailFactory(stateEntryEntity, UserName); 
       auditTrailList.Add(audit); 
      } 
     } 

     if (auditTrailList.Count > 0) 
     { 
      foreach (var audit in auditTrailList) 
      {//add all audits 
       //this.AddToDBAudit(audit); 
      } 
     } 

     return base.SaveChanges(); 
    } 
    private DBAudit AuditTrailFactory(ObjectStateEntry entry, string UserName) 
    { 
     DBAudit audit = new DBAudit(); 

     audit.UpdateDate = DateTime.Now; 
     audit.TableName = entry.EntitySet.Name; 
     audit.UserId = UserName; 

     if (entry.State == EntityState.Added) 
     {//entry is Added 
      audit.NewData = GetEntryValueInString(entry, false); 
      audit.Actions = AuditActions.I.ToString(); 
     } 
     else if (entry.State == EntityState.Deleted) 
     {//entry in deleted 
      audit.OldData = GetEntryValueInString(entry, true); 
      audit.Actions = AuditActions.D.ToString(); 
     } 
     else 
     {//entry is modified 
      audit.OldData = GetEntryValueInString(entry, true); 
      audit.NewData = GetEntryValueInString(entry, false); 
      audit.Actions = AuditActions.U.ToString(); 

      IEnumerable<string> modifiedProperties = entry.GetModifiedProperties(); 
      //assing collection of mismatched Columns name as serialized string 
      //audit.TableName = XMLSerializationHelper.XmlSerialize(modifiedProperties.ToArray()); 
     } 

     return audit; 
    } 

    private string GetEntryValueInString(ObjectStateEntry entry, bool isOrginal) 
    { 
     if (entry.Entity is EntityObject) 
     { 
      object target = CloneEntity((EntityObject)entry.Entity); 
      foreach (string propName in entry.GetModifiedProperties()) 
      { 
       object setterValue = null; 
       if (isOrginal) 
       { 
        //Get orginal value 
        setterValue = entry.OriginalValues[propName]; 
       } 
       else 
       { 
        //Get orginal value 
        setterValue = entry.CurrentValues[propName]; 
       } 
       //Find property to update 
       PropertyInfo propInfo = target.GetType().GetProperty(propName); 
       //update property with orgibal value 
       if (setterValue == DBNull.Value) 
       {// 
        setterValue = null; 
       } 
       propInfo.SetValue(target, setterValue, null); 
      }//end foreach 

      XmlSerializer formatter = new XmlSerializer(target.GetType()); 
      XDocument document = new XDocument(); 

      using (XmlWriter xmlWriter = document.CreateWriter()) 
      { 
       formatter.Serialize(xmlWriter, target); 
      } 
      return document.Root.ToString(); 
     } 
     return null; 
    } 
    public EntityObject CloneEntity(EntityObject obj) 
    { 
     DataContractSerializer dcSer = new DataContractSerializer(obj.GetType()); 
     MemoryStream memoryStream = new MemoryStream(); 

     dcSer.WriteObject(memoryStream, obj); 
     memoryStream.Position = 0; 

     EntityObject newObject = (EntityObject)dcSer.ReadObject(memoryStream); 
     return newObject; 
    } 

    public DbSet<Area> Areas { get; set; } 
    public DbSet<Country> Countries { get; set; } 
    public DbSet<Event> Events { get; set; } 
    public DbSet<Group> Groups { get; set; } 
    public DbSet<Holiday> Holidays { get; set; } 
    public DbSet<Location> Locations { get; set; } 
    public DbSet<Notification> Notifications { get; set; } 
    public DbSet<Receipt> Receipts { get; set; } 
    public DbSet<Report> Reports { get; set; } 
    public DbSet<Role> Roles { get; set; } 
    public DbSet<State> States { get; set; } 
    public DbSet<Store> Stores { get; set; } 
    public DbSet<TimeZone> TimeZones { get; set; } 
} 

}

回答

0
public partial class DbEntities 
{ 
    public enum AuditActions 
    { 
     I, 
     U, 
     D 
    } 
    public override int SaveChanges() 
    { 

      ChangeTracker.DetectChanges(); // Important! 

      ObjectContext ctx = ((IObjectContextAdapter)this).ObjectContext; 

      IEnumerable<ObjectStateEntry> changes = ctx.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified); 
      foreach (ObjectStateEntry stateEntryEntity in changes) 
      { 
       if (stateEntryEntity.EntitySet.Name != "MobileLoginDatas" && stateEntryEntity.EntitySet.Name != "SystemLookUps")//eliminate these tables 
       { 
        if (SessionData.userId != null && SessionData.userId != 0) //execute only after user login 
        { 
         if (!stateEntryEntity.IsRelationship && 
           stateEntryEntity.Entity != null && 
            !(stateEntryEntity.Entity is DBAudit)) 
         { 
          DBAudit audit = new DBAudit(); 
          audit.RevisionStamp = DateTime.Now; 
          audit.UserId = SessionData.userId; 
          audit.TableName = stateEntryEntity.EntitySet.Name; 
          audit.IPAddress = SessionData.clientIpAddress; 

          if (stateEntryEntity.State == EntityState.Added) 
          {//entry is Added 
           audit.Data = DictionaryToJsonConverter(GetEntryValueString(stateEntryEntity, false)); 

           audit.Action = AuditActions.I.ToString(); 
          } 
          else if (stateEntryEntity.State == EntityState.Deleted) 
          {//entry in deleted 
           audit.Data = DictionaryToJsonConverter(GetEntryValueString(stateEntryEntity, true)); 
           audit.Action = AuditActions.D.ToString(); 
          } 
          else 
          {//entry is modified 
           audit.Data = DictionaryToJsonConverter(GetEntryValueString(stateEntryEntity, false)); 
           audit.Action = AuditActions.U.ToString(); 
          } 
          this.Entry(audit).State = System.Data.EntityState.Added; 
         } 
        } 
       } 
      } 


     // } 
     return base.SaveChanges(); 
    } 
    ///convert the data to json 
    string DictionaryToJsonConverter(Dictionary<String, Object> dict) 
    { 
     var entries = dict.Select(d => 
      string.Format("'{0}': {1}", d.Key, string.Join(",", d.Value))); 
     return "{" + string.Join(",", entries) + "}"; 
    } 
    private Dictionary<string, object> GetEntryValueString(ObjectStateEntry entry, Boolean isOriginal) 
    { 
     var keyValues = new Dictionary<string, object>(); 
     var values = (IDataRecord) null; 
     if (isOriginal) 
     { 
      values = entry.OriginalValues; 
     } 
     else 
     { 
      values = entry.CurrentValues; 
     } 
     for (int i = 0; i < values.FieldCount; i++) 
     { 
      keyValues.Add(values.GetName(i), values.GetValue(i)); 
     } 
     return keyValues; 
    } 
}