【问题标题】:DbDataRecord - entry.CurrentValues and entry.originalValues are sameDbDataRecord - entry.CurrentValues 和 entry.originalValues 相同
【发布时间】:2013-11-26 07:33:38
【问题描述】:

我正在使用 Entity Framework 4.1,并且我有我的 DbContext 覆盖 SaveChanges 以审核属性更改。从“GetEntryValueInString”返回空值的代码。因为“如果(entry.Entity 是 EntityObject)”这个条件在所有情况下都失败了。如果我在评论条件时遇到另一个问题,例如 CurrentValues 和 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; }
}

}

【问题讨论】:

    标签: c# .net asp.net-mvc-3 entity-framework


    【解决方案1】:
    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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 1970-01-01
      • 1970-01-01
      • 2021-04-03
      • 1970-01-01
      • 2020-03-20
      • 1970-01-01
      相关资源
      最近更新 更多