将'tf'转换为布尔"String was not recognized as a valid Boolean."时出现流畅的 nhibernate 错误



当从数据库中获得布尔列记录时,我遇到了一个问题。我不能改变数据库结构。
数据库类型是Character(1) (PostgreSQL),他们使用't'表示真,'f'表示假。我已经使用了postgresql方言

我试着把这个放到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");

仍然不工作,任何帮助吗?

您可能需要在这里创建自己的用户类型。下面是一个创建自己的示例:

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类型。

确实,我做了这个自定义类型,它像一个魅力
(来源链接: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();
    }
}

还没有尝试过,但也许这可以工作:

Map(x => x.IsTemplate).Formula("case when template_p = 't' then 1 else 0 end")

我们使用的是postgres 8.3-8.4的布尔值,没有任何问题。然而,当使用基于ANTLR3的HQL解析器时,它开始对布尔替换变得挑剔,因此我们使用以下覆盖创建了自己的方言:

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

然而,我们使用了NHibernate.Dialect。postgresql82方言,不是通用的。你运行的是什么版本的postgres ?

编辑:哦,对不起,我没有注意到你有一个字符(1)列。也许这个会有帮助(用引号)?

return value ? "'t'" : "'f'";

相关内容

最新更新