This project is read-only.

Custom Properties not working

Apr 25, 2012 at 6:02 PM

How do we get the custom property code to work?  I need to have a solution that will perform an automatic lookup and get the value vs. the ID.  So, if I am auditing the Orders table which has a Product ID, I don't want to display the changed product ID, I want to display the actual product name which is in the Products table.  That was working in the initial version, but in version 2 it is not working, or at least theres no documentation on how to use it.  So, if anyone has a working version or can show me how to use it, that would be great.


Thank you.


May 1, 2012 at 11:52 PM

I've resolved it.  I have the full functionality of doddleaudit working if anyone's interested.  It was a matter of creating a lookup function that had the original datacontext.  But, you couldn't access the original data context as that would create a 'circular reference' type of situation.  So, I had to assign the table I needed to perform a lookup on in the OnCreated() event.  If anyone needs the full code, let me know and I'll post it.


May 12, 2012 at 10:50 AM
Edited May 12, 2012 at 10:50 AM

I'd like the new code, but the best way would be to do a fork (as I already did, fixing notably the old/new value bug), hoping that one day this project will be maintained again.

May 17, 2012 at 6:08 PM
Edited May 17, 2012 at 6:19 PM

yes post it please!


I'm trying to follow the example on, but I'm not sure how my custom AuditResolver class gets called.


edit:  found the solution,


would still like to see your code tho @intrinsic

May 18, 2012 at 11:15 PM


static private Table<LOOKUPTABLETYPE> lookupTable;


partial void



//Assign any lookup tables that need to be audited.


 MainTable.Audit().WithConfiguration<MainTableAuditConfig>(); }






 override void SaveAuditedEntity(AuditedEntity auditedEntity)









Just create a static table and use it when you need to perform the lookup for the property.




AuditProperty(m => m.lookupTableTypeId)

.GetValueFrom(lookupTableId => GetLookupTableType(lookupTabletypeId))


 //This is the same as the example code.









public class MainTableAuditConfig : EntityAuditConfiguration<LOOKUPTABLETYPE>




public string GetLookupTableType(int? lookuptableTypeID)




//return your string from your lookup table here

May 18, 2012 at 11:15 PM

This code editor is very bad.  Otherwise, my code would have been formatted.  Let me know if you need any more clarification.



May 21, 2012 at 8:33 AM
Thanx for ur help man..keep in touch have a great day...

On Sat, May 19, 2012 at 3:45 AM, intrinsic <> wrote:

From: intrinsic

This code editor is very bad. Otherwise, my code would have been formatted. Let me know if you need any more clarification.

Read the full discussion online.

To add a post to this discussion, reply to this email (

To start a new discussion for this project, email

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at

May 22, 2012 at 5:28 PM

no problem.  Did anyone have a more elegant solution than mine?  Basically, my solution was to create a static table and assign your lookup table to it as you can see above.  then, at least you have that table to perform the lookup when you need to within the auditconfig() method like so:

.GetValueFrom(typeId => GetType(typeId))


May 22, 2012 at 5:30 PM

Probably the author would have a more elegant solution.  But, I could only find the unit tests code (from the latest version) as an example to configure the auditing.  (Which had hardcode values, so it wasn't a practical solution for me.)



Dec 14, 2012 at 7:31 PM
Edited Dec 14, 2012 at 9:14 PM

No response from "author".  This is not good.  Incomplete solution

Dec 14, 2012 at 8:22 PM

He seems (and the other guy on the project) to have totally forgotten this project, which is very useful.


I would also love an Entity  Framework solution.


My we should start a new project.

Dec 14, 2012 at 8:57 PM

Sorry guys - I haven't used this project in over 4 years now. I've tried cleaning it up and adding some robust EF 4+ support... but life and other projects seem to always get in the way :)

Please feel free to start a new project though! If you happen to use any of my work then attribution would be much appreciated


Dec 14, 2012 at 9:29 PM

Oh you're back.  Great.  Just one question I have.  I am trying to get the lookup (custom property feature working)


If I have the following:


 AuditProperty(m => m.SubStationTypeId)
                .GetValueFrom(stid => GetSubstationType(stid))

How do I write the GetSubstationType() lookup method?

It would take an int? ID, and return a string.  I'm not familiar with linq functions.

Dec 14, 2012 at 11:33 PM

Do you even know how to use this or not?

Dec 17, 2012 at 11:52 PM

Complete garbage.  Incomplete, no documentation.  Author doesn't even know how to use his own product.  This project should be completely deleted from codeplex. 

Dec 18, 2012 at 12:03 AM
intrinsic wrote:

Complete garbage.  Incomplete, no documentation.  Author doesn't even know how to use his own product.  This project should be completely deleted from codeplex. 

How are those insults and ad hominen attacks on the author working out for you?

FYI, our company has been using DoddleAudit in production for years now, and despite a few rough edges early on, it's working great now.

Matt, I hope you ignore this ungrateful, ungracious member of codeplex. You have already explained that you no longer maintain this project, and that is fine. Thanks for taking the time to write and publish this software.

Dec 18, 2012 at 12:07 AM

rough edges?  Try, not working at all.  NO response from the author no matter what comments have been posted.  No documentation, full of bugs.  You can see I started this thread, and yet no one posts any working code except me?  Why is that?  Because you haven't managed to get the custom properties feature working either (which is critical in our case.), I'm sure of that.

Dec 18, 2012 at 12:17 AM

I agree with CombatWombat : maybe Matt was a bit slow in telling us he stopped this project, but anyway, he does not owe us anything.

Is somebody interested in created a new project based on this one ? With me ? I would like to work on the EF framework support.

Dec 18, 2012 at 12:26 AM

Figure it out and stop crying.  Are you a developer or aren't you?  Have you even tried looking at the source?  DoddleAudit also works fine for me in production. 

Despite your terrible attitude, here is what my custom property auditor looks like.  Hopefully it will help others out there, not just you. :p

    public class studentSchoolEnrolmentAuditConfig : EntityAuditConfiguration<studentSchoolEnrolment>  <- studentSchoolEnrolment  is linq model class


        public studentSchoolEnrolmentAuditConfig()


            AuditProperty(a => a.RegistrationStatusId)

                .GetValueFrom(a => DAL.Db.RegistrationStatus.Single(s => == a).code)  <- RegistrationStatus table contains all the 'types', "code" is a the string property for the actual registration status

                .WithPropertyName("Registration Status");




in my DataContext constructor:


            EntityAuditor<studentInfo> studentInfoAuditor = this.Audit<studentInfo>();

            studentInfoAuditor.Configuration.Relationships.Add(new RelatationshipConfiguration<studentSchoolEnrolment, studentInfo>()


My audit log entries get the appropriate Registration Status string instead of the numerical id.

I can't see how this would be a showstopper for you, since you could always post-process your Audit Viewer results and replace the id with the string that way.  However, the above is pretty convenient. =)



- kjm4


Dec 18, 2012 at 12:38 AM

I've looked at the source code for many hours.  This is almost identical to what I have.    in your .GetValueFrom() what is the "DAL.DB" ?  I can't seem to get a context of the table itself, so I can't perform the lookup.



Dec 18, 2012 at 12:45 AM
intrinsic wrote:

rough edges?  Try, not working at all.  NO response from the author no matter what comments have been posted.  No documentation, full of bugs.  You can see I started this thread, and yet no one posts any working code except me?  Why is that?  Because you haven't managed to get the custom properties feature working either (which is critical in our case.), I'm sure of that.


We have no need for custom properties.  We did require the ability to customise the audit data being created, which was solved by introducing an injection point (i.e. C# event with custom event args), fired after the audit data was created but before it was persisted to the database.

And yes, a couple of rough edges needed to be smoothed out, but it's working fine now. Specifically: work items #2321 and #2398 needed to be patched into the auditable data context, which is baked into our framework and installed on 200+ of our clients, each with millions of rows of audit data being created. So forgive me if I feel you're being overly critical of someone who obviously spent a lot of time writing this open source software.

Dec 18, 2012 at 12:49 AM

It's an http request-scoped static reference to my datacontext, google has tons of stuff on them.  It's stored in httpcontext.currentitems basically.  Since the tables references are "code type" tables, you should probably take them from a cache.

Really it can be anything that contains your IDs and string values.

Dec 18, 2012 at 12:55 AM

Ok.  But, this is database code.  Why are you mixing http requests with it?  I used a static table, but that will not work when you have one to many relationship tables that are audited, and the relationship tables don't have a corresponding foreign key.  Its like the context should already be there, but I can't get a reference to it, as the signature for GetValueFrom is like this:

        public CustomPropertyAuditor<TEntity, TProp> GetValueFrom(Expression<Func<TProp, string>> valueSelector)
            if (valueSelector == null) throw new ArgumentNullException("valueSelector");

            _propertySelector = valueSelector;
            return this;


so, even though the context of the table exists, you can never get a reference to it?  I shouldn't have to create a new context just for the lookup tables, as that will

be a circular reference.  So, theres something I'm missing that won't let me get a reference to the lookup tables.   Its like creating a duplicate context just go get it to work, but that isn't correct.

Dec 18, 2012 at 12:56 AM

Thanks for offering to help guys.

I do apologize that I haven't been able to maintain this specific project in a few years, but I've created 9 projects on codeplex and working as a developer on another. I'm sure you understand that it's difficult to work on all of them all of the time.

That said, if anyone who has been using this project for a while would like to be added as a Developer I would be happy to oblige. CombatWombat or kjm4, or anyone else, just let me know if you'd like to take it on!

Thanks again,


Dec 19, 2012 at 10:10 PM

Thanks.  got everything working now.  I still am not quite sure why there's no context to the lookup table within the linq expression?  Usually if you have a related table, you can simply write:


.GetValueFrom(maintable => maintable.lookuptable.code) 


In that case, you wouldn't need a separate data context to perform the lookup on.  I haven't written too many linq expressions, etc, but I can see that there is no context to the main table, only to the id within the .GetValueFrom() linq method, so I was quite confused about that for a while.


So, is there a way I can modify the linq methods to actually contain the context to the main table? 

Dec 20, 2012 at 12:38 AM

What about Auditing Something like GrandparentTable --> ParentTable --> ChildTable ,  along with Lookup tables for each level (e.g. ParentTable -->  ParentLookupTable) ?

What's the code I should use?  Is this possible at all?