Setup
As part of my data access layer, I am using Dapper with DapperExtensions and representing my database entities with models. Some of these models contain fields used for logging or change tracking, like so:
public class ExampleClass : BaseModel, ITypeWithChangeTracking
{
public int ExampleClassId { get { return Id; } set { Id = value; } }
public DateTime CreatedDate { get; set; }
public string CreatedBy { get; set; }
// More properties
}
public class ExampleClassMapper : ClassMapper<ExampleClass>
{
public ExampleClassMapper() : base()
{
Map(m => m.ExampleClassId).Key(KeyType.Identity);
Map(m => m.Id).Ignore();
base.AutoMap();
}
}
In this example, BaseModel is an abstract class that specifies the model has some integer Id (to make it easier to work with generics); ITypeWithChangeTracking specifies it should have the change tracking fields. So far, I've been able to shuffle most of the DAL logic into a generic implementation that can be shared among all models, and I'd like to keep that up with those that implement change tracking.
Tools Used
C#
Dapper
DapperExtensions
Problem
Some of the change tracking fields should be set when an object is inserted, but not when it is updated. I'm having trouble implementing this in a generic way that can be reused for each model.
Question
Is there anything I can use with Dapper or DapperExtensions to specify that a field should be included for an Insert, but ignored for an Update?
I've looked at various attributes such as ReadOnly and Ignore for mappings, but so far everything I've found is a blanket "always include" or "always ignore". Preferably, I'd like this to work with the standard Update() function and not require a specialized sproc, though I'm not sure that's possible. Any loopholes or useful decorators I'm missing?
(Note: Major brownie points if there's a way to shuffle this specification all the way up to the ITypeWithChangeTracking interface!)
Edit:
Rather than create separate models, I tweaked the code that was already setting the change tracking values from ITypeWithChangeTracking so that it would recognize unset values (null, DateTime.Min, etc). It was already checking to see whether the record was new or previously existing, so I had it fetch relevant values from the existing record if 1) the record did exist and 2) the model had unset change tracking values.