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

时间:2012-10-02 18:19:19

标签: .net sql-server-2008 sqldatareader

经常使用SQL Identity作为.NET对象的ID 在0或1处开始ID,因为不希望对象具有负ID 该ID将呈现给用户,因此它需要符合人类的逻辑。

也经常使用类似((Int32)key1<< 32)+ key2;哈希
如果无符号可以更快(UInt32)key1<< 32 | KEY2;

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

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

转换从0到最大的位置 直接投射不起作用(UInt16)Int16.Min = Int16.Max +1。
需要将Int16.Min转换为0,将Int16.Max转换为UInt16.Max。

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

目前有一种情况会破坏Int32 max但怀疑它会超过UInt32 max。如果确实超过了UInt32 max,那么应用程序和数据库将需要进行全面审核。

尝试扩展到SqlDataReader,它似乎有用。
将张贴作为答案。
尚未投入生产,因此请检查SO以获取更好的信息或警告该方法。

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

我们不使用Entity Framework,也不使用SQL LINQ。垃圾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 个答案:

答案 0 :(得分:1)

您可以将UInt32存储为SQL Server中的Int32。保存到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 Code First

公开一个Int32类型的属性,它只包装你的哈希值,并将实际的哈希属性标记为 NotMapped

private uint hash;

[NotMapped]
public uint Hash 
{ 
    get { return hash; }
    set { hash = value; }
}

public int HashAsLong 
{ 
    get { return hash; }
    set { hash = value; }
}

答案 1 :(得分:0)

最后我做了什么让对象负责翻译。

sqlID的只读签名属性 对于更新回数据库决定不应该乱用该值。

对象还公开了其他对象,哈希和UI使用的无符号ID。

相关问题