我尝试了许多不同的方法并查看了不同的帖子,但仍然没有遇到这种审计方式的解决方案。下面是我的 DBContext 模板文件。我通过添加OnContextCreated()
部分方法来自定义它并将SavingChanges
事件分配给我的OnSavingChanges
事件处理程序。
namespace ARSystem.Models
{
public partial class ARSEntities : ObjectContext
{
public ARSEntities()
: base("name=ARSEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public string UserName { get; set; }
List<DBAudit> auditTrailList = new List<DBAudit>();
public enum AuditActions
{
I,
U,
D
}
partial void OnContextCreated()
{
this.SavingChanges += new EventHandler(OnSavingChanges);
}
public void OnSavingChanges(object sender, EventArgs e)
{
IEnumerable<ObjectStateEntry> changes = this.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);
}
}
}
private DBAudit AuditTrailFactory(ObjectStateEntry entry, string UserName)
{
DBAudit audit = new DBAudit();
audit.AuditId = Guid.NewGuid().ToString();
audit.RevisionStamp = DateTime.Now;
audit.TableName = entry.EntitySet.Name;
audit.UserName = 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.ChangedColumns = 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<Student> Students { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<aspnet_Applications> aspnet_Applications { get; set; }
public DbSet<aspnet_Membership> aspnet_Membership { get; set; }
public DbSet<aspnet_Roles> aspnet_Roles { get; set; }
public DbSet<aspnet_SchemaVersions> aspnet_SchemaVersions { get; set; }
public DbSet<aspnet_Users> aspnet_Users { get; set; }
public DbSet<vw_aspnet_Applications> vw_aspnet_Applications { get; set; }
public DbSet<vw_aspnet_MembershipUsers> vw_aspnet_MembershipUsers { get; set; }
public DbSet<vw_aspnet_Roles> vw_aspnet_Roles { get; set; }
public DbSet<vw_aspnet_Users> vw_aspnet_Users { get; set; }
public DbSet<vw_aspnet_UsersInRoles> vw_aspnet_UsersInRoles { get; set; }
public DbSet<Cours> Courses { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Modules> Modules { get; set; }
public DbSet<EnrollmentsByCourse> EnrollmentsByCourse { get; set; }
public DbSet<EnrollmentsByCourseAudit> EnrollmentsByCourseAudit { get; set; }
public DbSet<DBAudit> DBAudit { get; set; }
}
}
但是,当我编译时,我收到以下错误消息:
错误 1 'ARSystem.Models.ARSEntities.OnModelCreating(System.Data.Entity.DbModelBuilder)':找不到合适的方法来覆盖 C:\Users\mngum\Documents\Visual Studio 2010\Projects\ARSystem\ARSystem\Models\ARSystem。上下文.cs 35 33 ARSystem
我在 DBContext 元数据类中看不到 OnContextCreated 方法,但我可以在 edmx 设计器中找到它。请让我知道如何实现该OnContextCreated()
方法,以便我可以覆盖SavingChanges
事件以进行审计。