经常使用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;
}
}
答案 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。