0

经常使用 SQL 标识作为 .NET 对象的 ID。
从 0 或 1 开始 ID,因为不希望对象具有负 ID。
ID 呈现给用户,因此它需要对人类来说是合乎逻辑的。

也经常使用类似 ((Int32)key1 << 32) + key2; 对于哈希
如果 unsigned 可以更快 (UInt32)key1 << 32 | 键2;

由于 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 兼容性,因为这个应用程序使用零并且永远不会。

我们不使用实体框架或 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;
    }
}  
4

2 回答 2

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 代码

公开一个仅包装散列值的 Int32 类型的属性,并将实际的散列属性标记为NotMapped

private uint hash;

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

public int HashAsLong 
{ 
    get { return hash; }
    set { hash = value; }
}
于 2012-10-02T18:21:43.460 回答
0

最后,我所做的就是让对象负责翻译。

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

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

于 2012-10-06T19:38:25.143 回答