2012-10-02 23 views
0

通常使用SQL Identity作为.NET对象的ID。
从0或1开始标识,因为不希望对象具有负ID。
该ID显示给用户,因此它需要符合人类。SqlDataReader将SQL签名转换为.NET无符号整数

也经常使用类似((Int32)key1 < < 32)+ key2;为散列
如果unsigned可以用更快的(UInt32)key1 < < 32 | KEY2;

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

在.NET中将SQL签名转换为无符号的最佳做法是什么?

其中转换从0到最大。
直接投射不能用作(UInt16)Int16.Min = Int16.Max +1。
需要将Int16.Min转换为0并将Int16.Max转换为UInt16.Max。

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

目前有一种情况,即将通过Int32 max吹,但怀疑它会永远超过UInt32 max。如果它确实超过了UInt32 max,那么应用程序和数据库将需要完整的评论。

试过对SqlDataReader的扩展,它似乎工作。
将作为答案发布。
尚未投入生产,因此请检查以获得更好的结果或警告有关该方法。

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

我们不使用实体框架也不使用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

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

SQLID的只读签名属性。
对于更新回数据库决定不应该混淆这个值。

这些对象还公开一个由其他对象,散列和UI使用的未签名ID。

1

您可以将您的UInt32作为Int32存储在SQL Server中。保存到SQL时,将未签名的整数转换为已签名的整数。

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

如果使用ADO。净

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; } 
} 
+0

在哪里和如何做铸造然后是我的问题?而不是保存这将只是身份。但会查询到该列。 – Paparazzi

+0

添加ADO.Net和实体框架代码第一个示例 –

+0

关于扩展...为什么使用更宽的整数作为临时变量?你只需要使用一个宽度相同的无符号整数,例如'Int32 int32 = rdr.GetInt16(i);'可以是'Uint16 uint16 = rdr.GetInt16(i);'。添加32768不会导致uint16溢出。它将不会大于0xffff。 –

相关问题