0

我有以下代码:

private static ISessionFactory CreateSessionFactory()
{
    ISessionFactory factory = null;

    var cfg = new Configuration();

    // Do this to map bool true/false to DB2 char('0') or char('1')
    var props = new Dictionary<string, string>(); 
    props.Add("query.substitutions","true=1;false=0");
    cfg.AddProperties(props);

    cfg.DataBaseIntegration(x =>
    {
        x.ConnectionString = CONNECTION_STRING;
        x.Dialect<DB2400Dialect>();
        x.Driver<DB2400Driver>();
    });

    factory = Fluently.Configure(cfg)
        .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))
        .BuildSessionFactory();

    return factory;
}

在我的 POCO 中,我有以下财产:

public virtual bool QCCount { get; set; }

在我的映射中,我有

Map(x => x.QCCount, "QCNT36");

在 DB2 中,没有位字段,只有带有 '0' 或 '1' 的 char(1)。

据我了解, props.Add("query.substitutions","true=1;false=0"); 应该将这些 0 和 1 映射到布尔 POCO 对象,但是,它似乎不起作用。

我是否需要在字段的映射中添加一些东西来告诉它使用它?

4

3 回答 3

2

我找到了一个似乎可行的解决方案。

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

我将“Y”、“N”更改为“0”和“1”,然后映射列并且处理正常。

代码:

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

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

    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 != "1" && trueFalse != "0")
            throw new Exception(string.Format("Expected data to be '0' or '1' but was '{0}'.", trueFalse));

        return trueFalse == "1";
    }

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

    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.QCCount, "QCNT36").CustomType<CharBoolType>();
于 2012-11-28T17:27:18.763 回答
1

似乎 NHibernate DB2 方言将布尔值映射到 SMALLINT(https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Dialect/DB2Dialect.cs):

RegisterColumnType(DbType.Boolean, "SMALLINT");

query.substitutions 用于将 HQL 查询中的某些标记自动替换为其他标记,我认为它不会影响阅读。

于 2012-11-28T17:05:50.580 回答
1

如果要将 SMALLINT 用于布尔列,则必须从 BooleanType 继承 usertype 类

代码:

public class IntBoolUserType : BooleanType, IUserType
{
    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.GetHashCode();
    }

    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 override SqlType SqlType
    {
        get
        {
            return new SqlType(DbType.Int32);
        }
    }

    public new SqlType[] SqlTypes
    {
        get { return new SqlType[] { SqlType }; }
    }

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

    public new void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        var val = !((bool)value) ? 0 : 1;
        NHibernateUtil.Int32.NullSafeSet(cmd, val, index);
    }

    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        return NHibernateUtil.Boolean.NullSafeGet(rs, names[0]);
    }

    public override void Set(IDbCommand cmd, object value, int index)
    {
        var val = !((bool)value) ? 0 : 1;
        ((IDataParameter)cmd.Parameters[index]).Value = val;
    }
}

映射:

Property(x => x.IsDeleted, map => { map.NotNullable(true); map.Type<IntBoolUserType>(); });
于 2014-02-01T16:57:12.030 回答