将't''f'转换为布尔值时,流畅的nhibernate错误“字符串未被识别为有效的布尔值。”

时间:2011-05-03 11:37:58

标签: c# nhibernate fluent-nhibernate

使用布尔列从数据库获取记录时遇到问题。我无法改变数据库结构 数据库类型是Character(1)(PostgreSQL),其中't'表示true,'f'表示false。我使用过PostgreSQLDialect。

我试过把它放在hibernate-configuration

 <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 个答案:

答案 0 :(得分:6)

您可能需要在此处创建自己的用户类型。以下是创建自己的示例:

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 :(得分:1)

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

答案 2 :(得分:0)

Haven没试过,但也许这可行:

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

答案 3 :(得分:0)

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

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

但是,我们使用的是NHibernate.Dialect.PostgreSQL82Dialect,而不是通用的。你在运行什么postgres版本?

编辑:哦,对不起,我没跟你说你有一个字符(1)列。也许这会有所帮助(带引号)?

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