свободная ошибка nhibernate при преобразовании 't' 'f' в логическое значение «Строка не была распознана как действительное логическое значение». - PullRequest
6 голосов
/ 03 мая 2011

У меня проблема при получении записи из базы данных с логическим столбцом. Я не могу изменить структуру базы данных.
Тип базы данных - Character (1) (PostgreSQL), где они использовали «t» для true и «f» для false. Я использовал PostgreSQLDialect.

Я пытался поместить это в конфигурацию hibernate

 <property name="query.substitutions">1 't',0 'f'</property>

Я пытался переопределить в диалекте

 public override string ToBooleanValueString(bool value)
        {
            return value ? "t" : "f";
        }

Отображение:

Map(x => x.IsTemplate).Column("template_p");

Все еще не работает, Любая помощь?

Ответы [ 4 ]

6 голосов
/ 03 мая 2011

Возможно, вам придется создать свой собственный тип пользователя здесь. Вот пример создания собственного:

http://lostechies.com/rayhouston/2008/03/23/mapping-strings-to-booleans-using-nhibernate-s-iusertype/

Тогда ваше отображение станет примерно таким:

Map(x => x.IsTemplate).Column("template_p").CustomType<MyCustomType>();

Редактировать:

Возможно, вы также сможете использовать стандартный тип YesNo, если сделаете что-то со своими подстановками запросов. Я не проверял это, но может быть что-то вроде этого:

<property name="query.substitutions">yes 't', no 'f'</property>

Ваше отображение будет выглядеть почти так же, как я говорил выше, за исключением того, что вы будете использовать тип YesNo.

1 голос
/ 04 мая 2011

Действительно Коул, я сделал этот нестандартный тип, и он работает как шарм
(ссылка на источник: https://lostechies.com/rayhouston/2008/03/23/mapping-strings-to-booleans-using-nhibernate-s-iusertype/)

public class TFType : IUserType
{
    public bool IsMutable
    {
        get { return false; }
    }

    public Type ReturnedType
    {
        get { return typeof(TFType); }
    }

    public SqlType[] SqlTypes
    {
        get { return new[]{NHibernateUtil.String.SqlType}; }
    }

    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var obj = NHibernateUtil.String.NullSafeGet(rs, names[0]);

        if(obj == null ) return null;

        var truefalse = (string) obj;

        if( truefalse != "t" && truefalse != "f" )
            throw new Exception(string.Format("Expected data to be 't' or 'f' but was '{0}'.", truefalse));

        return truefalse == "t";
    }

    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        if(value == null)
        {
            ((IDataParameter) cmd.Parameters[index]).Value = DBNull.Value;
        }
        else
        {
            var yes = (bool) value;
            ((IDataParameter)cmd.Parameters[index]).Value = yes ? "t" : "f";
        }
    }

    public object DeepCopy(object value)
    {
        return value;
    }

    public object Replace(object original, object target, object owner)
    {
        return original;
    }

    public object Assemble(object cached, object owner)
    {
        return cached;
    }

    public object Disassemble(object value)
    {
        return value;
    }

    public new bool Equals(object x, object y)
    {
        if( ReferenceEquals(x,y) ) return true;

        if( x == null || y == null ) return false;

        return x.Equals(y);
    }

    public int GetHashCode(object x)
    {
        return x == null ? typeof(bool).GetHashCode() + 473 : x.GetHashCode();
    }
}
0 голосов
/ 03 мая 2011

Мы используем postgres 8.3-8.4 с логическими значениями без проблем.Однако при использовании синтаксического анализатора HQL на основе ANTLR3 он начал придирчиво относиться к логическим подстановкам, поэтому мы создали собственный диалект со следующим переопределением:

public override string ToBooleanValueString( bool value )
{
    return value ? "true" : "false";
}

Однако мы использовали NHibernate.Dialect.PostgreSQL82Dialect, а не универсальныйодин.Какую версию postgres вы используете?

РЕДАКТИРОВАТЬ: О, извините, я не следил, чтобы у вас был столбец символов (1).может быть, это поможет вместо (с кавычками)?

return value ? "'t'" : "'f'";
0 голосов
/ 03 мая 2011

Не пробовал, но, возможно, это может сработать:

Map(x => x.IsTemplate).Formula("case when template_p = 't' then 1 else 0 end")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...