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

ブール列に 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 に答える
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 に答える