Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I also wanted to automate the population of audit fields on my MVC 4 / Entity Framework 5 application. I used information from @Eranga's answer and this blog: <a href="http://lourenco.co.za/blog/2013/07/audit-trails-concurrency-and-soft-deletion-with-entity-framework/" rel="nofollow noreferrer">http://lourenco.co.za/blog/2013/07/audit-trails-concurrency-and-soft-deletion-with-entity-framework/</a> to make this approach work for me with Ninject - posting in case valuable to anyone else:</p> <p>Created an interface and abstract class: </p> <pre><code>public interface IAuditableEntity { DateTime? CreatedDate { get; set; } string CreatedBy { get; set; } DateTime? LastModifiedDate { get; set; } string LastModifiedBy { get; set; } } public abstract class AuditableEntity:IAuditableEntity { public DateTime? CreatedDate { get; set; } public string CreatedBy { get; set; } public DateTime? LastModifiedDate { get; set; } public string LastModifiedBy { get; set; } } </code></pre> <p>Used them in my entities:</p> <pre><code>public class DataEntity : AuditableEntity { public int DataEntityID { get; set; } ... } </code></pre> <p>Added a constructor to MyDbContext which accepted the HttpContext and overrode SaveChanges:</p> <pre><code>public EFDbContext(HttpContext context) { _context = context; } public HttpContext _context { get; private set; } public override int SaveChanges() { DateTime currentDateTime = DateTime.Now; foreach (var auditableEntity in ChangeTracker.Entries&lt;IAuditableEntity&gt;()) { if (auditableEntity.State == EntityState.Added || auditableEntity.State == EntityState.Modified) { auditableEntity.Entity.LastModifiedDate = currentDateTime; switch (auditableEntity.State) { case EntityState.Added: auditableEntity.Entity.CreatedDate = currentDateTime; auditableEntity.Entity.CreatedBy = _context.User.Identity.Name; break; case EntityState.Modified: auditableEntity.Entity.LastModifiedDate = currentDateTime; auditableEntity.Entity.LastModifiedBy = _context.User.Identity.Name; if (auditableEntity.Property(p =&gt; p.CreatedDate).IsModified || auditableEntity.Property(p =&gt; p.CreatedBy).IsModified) { throw new DbEntityValidationException(string.Format("Attempt to change created audit trails on a modified {0}", auditableEntity.Entity.GetType().FullName)); } break; } } } return base.SaveChanges(); } </code></pre> <p>Finally - need to have a DbContext per request and pass HttpContext as below based on this answer: <a href="https://stackoverflow.com/a/3617961/1803682">https://stackoverflow.com/a/3617961/1803682</a> - note that as <code>MyDbContext</code> is now Request scope, the Repositories must be as well.</p> <pre><code>kernel.Bind&lt;IDataRepository&gt;() .To&lt;EFDataRepository&gt;() .InRequestScope(); kernel.Bind&lt;MyDbContext&gt;().ToSelf() .InRequestScope() .WithConstructorArgument("context", ninjectContext=&gt;HttpContext.Current); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload