3

I am starting to use Fluent nHibernate on a project and am trying to get the automapping to work. At the time I am stuck with the mapping of our database's timestamp fields into byte-arrays. We are using SQL Server 2008 as the database, and we are not generating the database from code.

What I have:

public class Entity
  {
        public virtual Guid RowID { get; protected set; }
        public virtual byte[] ChangeCheck { get; protected set; }
        public virtual string Data { get; set; }
  }

Our database convention is to name the version field 'ChangeCheck'. I cannot seem to locate where I override the default behaviour of DefaultAutomappingConfiguration to use ChangeCheck as the auto-generated version field.

Is it possible to get a DefaultAutomappingConfiguration sub-class to automap all ChangeCheck fields into version fields?

Thanks for any pointers and help.

Optional solution:

Given I create an automap override for all entities using 'ChangeCheck' I could do the following:

 private class ChangeCheckVersionConvention : IVersionConvention
    {
        public void Apply(IVersionInstance instance)
        {
            instance.Column("ChangeCheck");
            instance.Generated.Always();
            instance.UnsavedValue(null);
        }
    }

public class EntityOverride : IAutoMappingOverride<IssueReport>
    {
        public void Override(AutoMapping<IssueReport> mapping)
        {
            mapping.Version(m => m.ChangeCheck);
        }
     }

 //....
 var persistenceModel = AutoMap.AssemblyOf<MyConfiguration>(new MyConfiguration())
            .UseOverridesFromAssemblyOf<MyConfiguration>()
            .Conventions.Add<ChangeCheckVersionConvention>();

Which works, however I cannot figure out how to remove the override to get the ChangeCheck column set-up as my Version column without having to override all my entities.

1 Answer 1

2

After not getting anywhere I decided to step through the Fluent nHibernate code to see what was happening. I then located how the 'DefaultAutomappingConfiguration' was setup, and created my own version:

public class MyAutomappingStoreConfiguration : DefaultAutomappingConfiguration
{
    public override IEnumerable<IAutomappingStep> GetMappingSteps(AutoMapper mapper, IConventionFinder conventionFinder)
    {
        return new IAutomappingStep[]
        {
            new IdentityStep(this),
            new MyChangeCheckVersionStep(this),
            new ComponentStep(this, mapper),
            new PropertyStep(conventionFinder, this),
            new HasManyToManyStep(this),
            new ReferenceStep(this),
            new HasManyStep(this)
        };
    }
}

Note the MyChangeCheckVersionStep which is what is different. I then implemented a VersionStep class that added ChangeCheck to the list of column names that are assumed to be Version columns:

public class MyChangeCheckVersionStep: IAutomappingStep
{
    private static readonly IList<string> validNames 
         = new List<string> { "version", "timestamp", "changecheck" };
    private static readonly IList<Type> validTypes
         = new List<Type> { typeof(int), typeof(long), typeof(TimeSpan), typeof(byte[]) };

    private readonly IAutomappingStep defaultVersionStep;

    public MyChangeCheckVersionStep(IAutomappingConfiguration cfg)
    {
        this.defaultVersionStep = new VersionStep(cfg);
    }

    public bool ShouldMap(Member member)
    {
        return validNames.Contains(member.Name.ToLowerInvariant())
           && validTypes.Contains(member.PropertyType);
    }

    public void Map(ClassMappingBase classMap, Member member)
    {
        defaultVersionStep.Map(classMap, member);
    }
}

The class basically calls the defualt VersionStep implementation for everything but ShouldMap.

Now I no longer need to create overrides for each entity to get the Version working. Note as well, that I still use the ChangeCheckVersionConvention - it is the override on every entity class I no longer need.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.