代码之家  ›  专栏  ›  技术社区  ›  paparazzo

SqlDataReader将SQL有符号整数转换为.NET无符号整数

  •  0
  • paparazzo  · 技术社区  · 12 年前

    通常使用SQL标识作为.NET对象的ID。
    在0或1处启动ID,因为不希望对象具有负ID。
    ID被呈现给用户,因此它需要对人类具有逻辑性。

    还经常使用类似于((Int32)key1<<32)+键2;用于散列
    如果unsigned可以用更快的(UInt32)key1<<32|键2;

    由于SQL没有无符号数据类型,因此丢失了一半的范围。

    在.NET中从SQL签名转换为无签名的好方法是什么?

    转换从0到最大的位置。
    直转换不能作为(UInt16)Int16.最小值=Int16.最大值+1。
    需要将Int16.最小值转换为0,将Int16.最大值转换为UInt16.最大值。

    在SQL中,将数据类型的标识种子设置为最小值(或最小值+1)。

    目前的情况是,它将突破Int32 max,但怀疑它是否会超过UInt32 max。如果它确实超过了UInt32 max,应用程序和数据库将需要全面审查。

    尝试了SqlDataReader的扩展,它似乎可以工作。
    将作为答案发布。
    尚未投入生产,因此请检查so是否有更好的东西或有关该方法的警告。

    不需要DataTable兼容性,因为此应用程序使用零并且永远不会使用。

    我们既不使用实体框架,也不使用SQL LINQ。Grunge TSQL和SP。

    public static class MyExtensions
    {
        public static UInt16 GetUInt16(this SqlDataReader rdr, int i)
        {
            //return (UInt16)rdr.GetInt16(i);  // wrong answer
            Int16 int16 = rdr.GetInt16(i);
            UInt16 uint16 = (UInt16)(int16 + 32768);
            return uint16;
        }
        public static UInt32 GetUInt32(this SqlDataReader rdr, int i)
        {
            Int32 int32 = rdr.GetInt32(i);
            UInt32 uint32 = (UInt32)(int32 + 2147483648);
            return uint32;
        }
    }  
    
    2 回复  |  直到 12 年前
        1
  •  1
  •   Eric J.    12 年前

    您可以将UInt32作为Int32存储在SQL Server中。保存到SQL时,将无符号整数强制转换为有符号整数。

    大于Int32.MaxValue的UInt32值将在SQL中表示为负数,但您可以在从数据库读取后将其强制转换回UInt32。

    如果使用ADO.Net

    uint hash;
    

    读取数据时

    while (reader.Read())
    {
        uint hash = (uint)reader.GetInt32(myIndex);
    }
    

    写入数据时

    cmd.Parameters.AddWithValue("MyParamName", (int)hash);
    

    如果首先使用EF代码

    公开一个Int32类型的属性,该属性只包装您的哈希值,并将实际的哈希属性标记为 未映射

    private uint hash;
    
    [NotMapped]
    public uint Hash 
    { 
        get { return hash; }
        set { hash = value; }
    }
    
    public int HashAsLong 
    { 
        get { return hash; }
        set { hash = value; }
    }
    
        2
  •  0
  •   paparazzo    12 年前

    最后,我所做的事情使对象负责翻译。

    sqlID的只读签名属性。
    对于返回数据库的更新,决定不应干扰该值。

    这些对象还公开了一个未签名的ID,该ID由其他对象、哈希和UI使用。