【问题标题】:Map SQLDecimal property in NHibernate在 NHibernate 中映射 SQLDecimal 属性
【发布时间】:2015-04-10 09:26:11
【问题描述】:

我正在尝试从 SQL Server 数据库中读取小数点 (38,16) 并苦苦挣扎。经过大量阅读后,我尝试使用以下代码为 SQL Decimal 实现自定义类型:

public class BigDecimal : IUserType
    {
        public bool Equals(object x, object y)
        {
            return object.Equals(x,y);
        }

        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }

        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            int index = rs.GetOrdinal(names[0]);
            object result = rs.GetValue(index);
            return result;
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            //Not got here yet
        }

        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 SqlType[] SqlTypes { get { return new[] {SqlTypeFactory.Decimal}; } }
        public Type ReturnedType { get { return typeof (SqlDecimal); } }
        public bool IsMutable { get { return false; } }
    }

但是 rs.GetValue 的输出是一个小数,而不是 SQLDecimal,这会导致溢出异常。

类如下所示:

public class Billy
{
    public BigDecimal TheNumber {get;set;}
}

映射如下所示:

public class BillyMap : ClassMap<Billy>
{
    public BillyMap()
    {
        Map(b=>b.TheNumber).CustomType<BigDecimal>();
    }
}

请有人告诉我哪里出错了。

【问题讨论】:

    标签: nhibernate fluent-nhibernate nhibernate-mapping fluent-nhibernate-mapping custom-type


    【解决方案1】:

    我认为您需要将阅读器转换为 SqlDataReader,以便您可以访问 GetSqlDecimal() 或 GetSqlValue(),因为 GetValue() 将转换为基本的 .Net Framework 类型。来自'https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getsqlvalue%28v=vs.110%29.aspx':

    GetSqlValue 使用本机 SQL Server 类型返回数据。要使用 .NET Framework 类型检索数据,请参阅 GetValue。

    【讨论】:

    • 谢谢,但它不是 SqlDataReader 或从一个。我会告诉你我最后做了什么......
    【解决方案2】:

    最后,我做了一个在 SQL 中执行转换的东西,并将其设为属性部分,然后在所有映射文件上使用它:

        private const string DECIMAL_CONVERSION = "(CONVERT(decimal(28,6), [{0}]))";
    
        private static string MapDecimalProperty(string fieldName)
        {
            return string.Format(DECIMAL_CONVERSION, fieldName.Trim('[',']'));
        }
    
        public static PropertyPart LongDecimal(this PropertyPart part, string fieldName)
        {
            return part.Formula(MapDecimalProperty(fieldName));
        }
    

    关于映射:

    Map(ep => ep.BigDecimalField).EDWDecimal("[BigDecimalField]");
    

    这暂时有效。我已通知数据架构团队,这正在发生,他们认为这不会对任何当前数据造成问题,并将在未来的开发中考虑它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2016-10-07
      • 2012-03-10
      相关资源
      最近更新 更多