I tried many different ways and looked at different posts, but still have not found a solution for this audit method. The following is a DBContext template file. I configured it by adding the partial OnContextCreated() method and assigning the SavingChanges event SavingChanges my SavingChanges event handler.
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; } } }
However, when compiling, I get an error message:
Error 1 'ARSystem.Models.ARSEntities.OnModelCreating (System.Data.Entity.DbModelBuilder)': no ββsuitable method was found to override C: \ Users \ mngum \ Documents \ Visual Studio 2010 \ Projects \ ARSystem \ ARSystem \ Models \ ARSystem. Context.cs 35 33 ARSystem
I do not see the OnContextCreated method in the DBContext metadata class, but I can find it in the edmx designer. Please let me know how I can implement the OnContextCreated() method so that I can override the SavingChanges event for audit purposes.
source share