Как сопоставить поле UInt64 десятичному (20, 0) столбцу с помощью Fluent nHibernate? - PullRequest
2 голосов
/ 19 сентября 2011

Я использую

  • MS SQL Server 2008R2
  • Свободный nHibernate 1.3
  • nHibernate 3.2

В моем домене есть поле UInt64, которое потенциально может занимать весь диапазон UInt64. Поскольку MS-SQL не поддерживает целые числа без знака, мы решили сохранить его в столбце decimal(20,0) (по крайней мере, на данный момент). Я попытался использовать CustomSqlType("decimal(20, 0)") для этого столбца в моих сопоставлениях, но все еще получаю сообщение об ошибке, когда пытаюсь получить доступ к этому полю, в котором говорится, что база данных не поддерживает UInt64.

Как сопоставить поле UInt64 десятичному (20, 0) столбцу с помощью Fluent nHibernate?

Я пробовал

  • CustomSqlType ( "Десятичный"). Точность (20) .Scale (0)
  • CustomSqlType ("десятичный (20, 0)")
  • CustomType () и перестановки CustomSqlType и CustomType.

Редактировать Это сообщение об ошибке: «От DbType UInt64 не существует сопоставления известному SqlDbType».

Редактировать 2 Это работает для стороны записи, но разрывается с неверным приведением, когда значения считываются обратно

.CustomSqlType("decimal").Precision(20).Scale(0)
.CustomType<NHibernate.Type.DoubleType>()

1 Ответ

3 голосов
/ 20 сентября 2011

Я бы пошел с типом пользователя

class UInt64UserType : ImmutableUserType
{
    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var value = NHibernateUtil.Decimal.NullSafeGet(rs, names[0]);
        return (value == null) ? 0 : Convert.ToUInt64(value);
    }

    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        decimal d = Convert.ToDecimal(value);
        NHibernateUtil.Decimal.NullSafeSet(cmd, d, index);
    }

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

    public SqlType[] SqlTypes
    {
        get { return new[] { SqlTypeFactory.Decimal }; }
    }
}


.CustomType<UInt64UserType>()

Редактировать: извините, забыл заметить.У меня много пользовательских типов, поэтому я реализовал свои собственные базовые классы

public abstract class ImmutableUserType : UserTypeBase
{
    public override bool IsMutable
    {
        get { return false; }
    }

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

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

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

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

public abstract class UserTypeBase : IUserType
{
    public new virtual bool Equals(object x, object y)
    {
        return EqualsHelper.Equals(x, y);
    }

    public virtual int GetHashCode(object x)
    {
        return (x == null) ? 0 : x.GetHashCode();
    }

    public abstract object Assemble(object cached, object owner);

    public abstract object DeepCopy(object value);

    public abstract object Disassemble(object value);

    public abstract bool IsMutable { get; }

    public abstract object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner);

    public abstract void NullSafeSet(System.Data.IDbCommand cmd, object value, int index);

    public abstract object Replace(object original, object target, object owner);

    public abstract Type ReturnedType { get; }

    public abstract SqlType[] SqlTypes { get; }
}
...