我正在使用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; }
}
}
最佳答案
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;
}
}
关于c# - DbDataRecord-entry.CurrentValues和entry.originalValues相同,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20211041/