Question

For an ASP.NET MVC application that I'm developing, my entities are going against pre-existing tables that have columns designed to track database transactions (LastModDate, LastModByUserId, CreateDate,CreateByUserId), but aren't set up with triggers of their own to automatically populate these columns. I'm a bit out of my comfort zone as in the past I've only worked with tables that either have these columns populated via database triggers or have transaction tracking done manually but in a separate table (usually something I've seen in dealing with ESBs and ordering systems).

My assumption for why these columns are set up this way is to override fields relating to who the user is, in scenarios where the user is authenticated but the web application connection to the database is done through an application user account.

So my question is in designing Models that map to these tables do I just extend a "DBEntity" type class and call an "Update/Updated" routine prior to doing any modifications? Also, is having these type of manually populated transaction columns common? Thanks.

public class DBEntity
{
    //Primary Key
    public int Id { get; set; }
    public DateTime LastModDate {get; set;}
    public int LastModByUserId {get; set;} 
    public DateTime CreateDate {get; set;}
    public int CreateByUserId {get; set;}

    public DBEntity(UserLogin currentUser)
    {
        CreatedDate=DateTime.Now;
        CreatedByUserId=currentUser.Id;
        Updated (UserLogin);
    }
    public void Updated (UserLogin user)
    {
        LastModDate =DateTime.Now;
        LastModUserId =user.Id;
    }
}
public class UserLogin : DBEntity
{        
    public string Name { get; set; }
    public string UserName { get; set; }
    public string UserPassword { get; set; }
}
Was it helpful?

Solution

You could make the property set methods protected/private and do a similar thing MVC uses with html helpers.

So you would end up with something like:

someEntity.Update( x => x.Property, propertyValue, user);

If you are confused I can post the Update method declaration.

I am not sure about whether this scenario is common but I certainly think it would be a better idea to implement that as database triggers. But if you must do it manually I think this is the best you can do to automate the process.

EDIT:

Here you go

public class DBEntity
{
    public short Prop1 { get; protected set; }
    public string Prop2 { get; protected set; }

    public DBEntity()
    {
    }

    public void Update<T>( Expression<Func<DBEntity, T>> outExpr, T value)
    {
        if (value != null)
        {
            var expr = (MemberExpression)outExpr.Body;
            var prop = (PropertyInfo)expr.Member;
            prop.SetValue(this, value, null);
        }
    }

}

Test:

static void Main(string[] args)
{
    DBEntity e = new DBEntity();
    e.Update<string>(x => x.Prop2, "test");
    Console.WriteLine(e.Prop2);
}

Leave me a comment if you still have any questions. Good luck!

OTHER TIPS

You could look into overriding the DbContext.SaveChanges() method to update your create/update tracking fields (ObjectContext has a SavingChanges event if you are using that instead of DbContext).

You would probably want to create an interface for the fields, and then in SaveChanges() you could use the ChangeTracker to find the added and modified entities, and if they implement your interface, cast and update the properties.

This answer has some code that does something similar.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top