Сохранить все строковые значения в нижнем регистре

#nhibernate #fluent-nhibernate #fluent-nhibernate-mapping

#nhibernate #свободно-nhibernate #свободно-nhibernate-сопоставление

Вопрос:

Я хотел бы использовать нижний регистр для всех строковых значений, прежде чем сохранять их в db.

Есть ли какой-либо способ, которым NHibernate может это сделать и как? Также есть ли какие-либо последствия для производительности, о которых я должен знать?

Ответ №1:

Одним из способов добиться этого было бы введение пользовательского типа для преобразования. Что-то вроде:

 [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
}
  

Затем вы можете либо сопоставить требуемые свойства с этим типом, например:

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

Или даже зарегистрировать его как тип по умолчанию для всех сопоставлений строк (по крайней мере, это верно для последней версии NHibernate 5.2):

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