c# - Audit Logging Inserts -
i wondering if offer input implementation of audit logging inserts. need ensure transactional.
i have audit dbset built upon following poco:
public class audit { public int id { get; set; } public user user { get; set; } public datetime created { get; set; } public string type { get; set; } public int entityid { get; set; } public string message { get; set; } }
i have dbset, users, when insert want create automatically add audit entity in audit dbset. consider following code:
//var user = new user(); //user.created = datetime.now; //user.username = "testuser"; //user.password = "testpassword"; //datacontext.users.add(user); var post = new post(); post.created = datetime.now; post.title = "a sample post"; post.published = true; post.body = "some content goes in here..."; datacontext.posts.add(post); var audit = new audit(); audit.created = datetime.now; audit.user = currentuser.user; // logged in user audit.type = "post.add"; audit.entityid = post.id; audit.message = "new post created"; datacontext.audits.add(audit); datacontext.savechanges();
in instance, audit entity added "entityid" property set 0 (default value) , not identity of created user post, i.e. identity value (scope_identity()/@@identity).
i'd keep both points in single transaction, rather split items 2 transactions, i.e. persist user post first, persist audit second there chance audit may fail.
override dbcontext.savechanges() , @ changetracker.entries().where(e=>e.state != entitystate.unchanged).
here example r&d project of mine:
public override int savechanges() { int recordsupdated = 0; var journalentries = new list<auditjournal>(); foreach (var entry in this.changetracker.entries<itrackedentity>().where(e=>e.state != entitystate.unchanged)) { auditjournal journal = new auditjournal(); journal.id = guid.newguid(); journal.entityid = entry.entity.id.value; journal.entitytype = entry.entity.entitytype; journal.actiontype = entry.state.tostring(); journal.occurredon = datetime.utcnow; //journal.userid = current user //journal.previousentitydata = xml serialization of original entitty journalentries.add(journal); } using (var scope = new transactionscope()) { recordsupdated = base.savechanges(); foreach (var journalentry in journalentries) this.auditjournal.add(journalentry); base.savechanges(); //save journal entries scope.complete(); } return recordsupdated; } //every entity needs audited has implement interface public interface itrackedentity { string entitytype { get; } guid? id { get; set; } }
Comments
Post a Comment