nhibernatefluent-nhibernatefluent-nhibernate-mapping

Save all string values in lowercase


I would like to lower case all string values before saving them do db.

Is there any way NHibernate can do this and how ? Also are there any performance implications that I should be aware of ?


Solution

  • One way to achieve it would be introducing custom type for conversion. Something like:

    [Serializable]
    public class LowerCaseStringType : AbstractStringType, ILiteralType
    {
        public LowerCaseStringType() : base(new StringSqlType())
        {
            //To avoid NHibernate to issue update on flush when the same string is assigned with different casing
            Comparer = StringComparer.OrdinalIgnoreCase;
        }
    
        public override string Name { get; } = "LowerCaseString";
    
        public override void Set(DbCommand cmd, object value, int index, ISessionImplementor session)
        {
            base.Set(cmd, ((string) value)?.ToLowerInvariant(), index, session);
        }
    
        //Called when NHibernate needs to inline non parameterized string right into SQL. Not sure if you need it
        string ILiteralType.ObjectToSQLString(object value, Dialect.Dialect dialect)
        {
            return "'" + ((string) value).ToLowerInvariant() + "'";
        }
    
        //If you also want to retrieve all values in lowercase than also override Get method
    }
    

    Than you can either map required properties with this type like:

    <property name="Name" type="YourNamespace.LowerCaseStringType, YourAssemblyName">
    

    Or even register it as default type for all string mappings (at least it's true for latest NHibernate 5.2):

    //Somewhere before SessionFactory is created
    TypeFactory.RegisterType(typeof(string), new LowerCaseStringType(), new[] {"string", "String"});