【问题标题】:NHibernate - How to store UInt32 in databaseNHibernate - 如何将 UInt32 存储在数据库中
【发布时间】:2010-02-22 05:49:25
【问题描述】:

使用 NHibernate 将 UInt32 类型映射到 sql-server int 类型的最佳方法是什么。

该值是图片宽度/高度,因此负值在这里没有意义。

但也许我应该使用 int,因为 NHibenate 不支持未分配的整数。

【问题讨论】:

    标签: nhibernate nhibernate-mapping uint32


    【解决方案1】:

    您可以使用 IUserType 映射列。

    <class name="UnsignedCounter">
        <property name="Count" type="mynamespace.UInt32Type, mydll"  />
    </class>
    

    以及映射UInt32?UInt32 的IUserType。

    class UInt32Type : IUserType
    {
        public object NullSafeGet( System.Data.IDataReader rs, string[] names, object owner )
        {
            int? i = (int?) NHibernateUtil.Int32.NullSafeGet( rs, names[0] );
            return (UInt32?) i;
        }
    
        public void NullSafeSet( System.Data.IDbCommand cmd, object value, int index )
        {
            UInt32? u = (UInt32?) value;
            int? i = (Int32?) u;
            NHibernateUtil.Int32.NullSafeSet( cmd, i, index );
        }
    
        public Type ReturnedType
        {
            get { return typeof(Nullable<UInt32>); }
        }
    
        public SqlType[] SqlTypes
        {
            get { return new SqlType[] { SqlTypeFactory.Int32 }; }
        }
    
        public object Assemble( object cached, object owner )
        {
            return cached;
        }
    
        public object DeepCopy( object value )
        {
            return value;
        }
    
        public object Disassemble( object value )
        {
            return value;
        }
    
        public int GetHashCode( object x )
        {
            return x.GetHashCode();
        }
    
        public bool IsMutable
        {
            get { return false; }
        }
    
        public object Replace( object original, object target, object owner )
        {
            return original;
        }
    
        public new bool Equals( object x, object y )
        {
            return x != null && x.Equals( y );
        }
    }
    

    【讨论】:

    • 从带有NullSafeSet 的uint Enum 类型转换时出现问题:在这种情况下无法将值转换为可为空的类型。请改用uint? u = null; if (value != null) u = (uint)value;
    • 也等于不能正常工作。工作版本可能是public new bool Equals(object x, object y) { if (object.ReferenceEquals(x, y)) { return true; } if (x == null || y == null) { return false; } return (uint)x == (uint)y; }
    • @fmuecke:在这种情况下,Equals 将始终接收装箱值,因此 object.ReferenceEquals 将始终返回 false,并且它们永远不会为空。
    【解决方案2】:

    我迟到了一年,但由于我有同样的问题并找到了不同的答案,我想我会添加它。它似乎更简单。也许它有一个我还没有发现的缺陷。

    我正在使用 NHibernate 3.0、Visual Studio 2005 和 .NET 2.0.x。

    我发现我可以使用 .NET 的 UInt32 类并且不在 hbm.xml 中包含 type 属性。

    // .NET 2.0 Property syntax
    public class MyClass
    {
       // NHibernate needs public virtual properties. 
       private UInt32 _Id;
       public virtual UInt32 Id { get { return (_Id); } set { _Id = value; } }
    }
    
    
    // hbml.xml
    <class name ="MyClass">
       <id name="Id" />
    </class>
    
    
    // SQL to create the table
    CREATE TABLE `PumpConnection` (
    `Id` **INT**(10) **UNSIGNED** NOT NULL AUTO_INCREMENT,
    )
    

    【讨论】:

    • 您尝试sql-type 使用模式生成吗?
    • 不确定这是否是一个缺陷,但我尝试了类似简单的方法并遇到了值 > 2^31 的问题:读取时,它们通过 NH 的管道以 Int64 的形式返回(签名! ) 并成为相同位的负数(二进制补码?)表示 - 然后抛出异常,因为负数表示不适合数据类型 UInt32。我在 NHibernate 5 上,我的特定映射是这样的:map.Component&lt;Color&gt;(x =&gt; x.Color, m =&gt; { m.Property(m =&gt; m.Value); }); 点是,我猜....你试过这个值 > 2^31 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    相关资源
    最近更新 更多