使用VB.net,创建一个名为staff的新类,具有三个属性: Name,LastName,ID - 应该适合用作数据库中的主键。
提供一个类构造函数来填充Name和LastName。 ID应该在构造函数中自动生成,不应该传入。
我知道如何创建类,属性和构造函数,我只需要知道如何在构造函数中自动生成ID字段。是否有可能做到这一点?
我通常做的是将数据库中的id字段作为标识字段和主键,以便自动插入下一个可用的id或在我的应用程序中,我从数据库中读取最后一个ID并添加一个。但我需要知道如何在构造函数中自动生成ID字段。
答案 0 :(得分:6)
如果您对ID类型没有任何约束,可以使用GUID:
Dim id As Guid = Guid.NewGuid()
您甚至可以将其保留为字符串:
Dim id As String = Guid.NewGuid().ToString("N")
应该授予它在不同机器上的唯一性(以满足您的要求,它必须适合用作数据库中的主键)。另请参阅this post。
情况更糟,如果您没有这样严格的要求(网络中的唯一性),您可以使用时间戳。当然,在这种情况下,您必须考虑更多问题:
如果满足所有这些条件:
每次构造新对象时,您都可以使用Shared
计数器递增。如果系统计时器粒度不是问题(请参阅有关时间戳的段落),则可以使用system up time作为ID。由于有关粒度的限制,即使同时运行同一应用程序的多个实例,它也应该有效。
如果您使用Shared
字段,则必须处理同步问题。根据{{3}}中的建议,您可以使用SyncLock
。作为替代方案,您可以使用Interlocked.Increment
操作。
如果计数器的所有条件都满足,那么这个也是:
ValueType
,并且它不会覆盖GetHashCode()
方法。您可以使用哈希码(使用GetHashCode()
获得),因为(来自this comment):
换句话说,ReferenceEquals方法返回true的两个对象具有相同的哈希码。
因为Object.ReferenceEquals()
仅在比较同一个实例时返回true
,所以每个实例都将具有唯一的哈希码(因为在32位应用程序哈希代码中是对象引用本身)。请注意,这是一个实现细节,可能会发生变化。
我知道这可能会让某人感到震惊,但64位值的好随机数生成器碰撞概率非常低。我重复极低概率(有关更多数学详细信息,请参阅MSDN)。只是不要使用System.Random
!
根据您使用的种子,您也可以在网络场景中生成随机数(不要忘记 - 需要引用 - 一个本地网络协议的早期草案提出了一个32位随机数作为地址,它已被由于用户反馈不好而改变了,但这并不意味着它无法正常工作)。
答案 1 :(得分:0)
你想要一个不会重复的数字!那么为什么不使用它?
Dim dateAndTime As Date
dateAndTime = Now
TextBoxPID.Text = Format(dateAndTime, "yyyyMMddHHmmss").ToString
除非您的数据条目将在几毫秒内完成,否则此解决方案效果很好。如果您遇到毫秒问题,那么只需在字符串末尾添加一个计数器。
counter +=1
TextBoxPID.Text = Format(dateAndTime, "yyyyMMddHHmmss").ToString & counter.ToString
如果您正在使用网络并让多个人进行数据输入,请将其员工ID添加到字符串中。每个问题都有简单的解决方案,但在大多数情况下,如果不是所有情况,这都可以毫无问题地工作。
答案 2 :(得分:0)
我的要求有点不同;但我需要生成一个随机且唯一的用户ID,即10个数字,花费公平时间无法找到合适的解决方案。 所以我最终得到了以下功能;其独特而随机的结果。
根据一台测试机器上的一个应用程序瞬间,它是增量的唯一结果;因为用户将在非预选择时间戳上生成十位数字。除了使用随机alpha前缀;我希望这个功能可以提供解决方案:
Imports System.Globalization
Imports System.Net
Public Class GetNetTime
Public Shared Function GetUTC()
' connect to google servers
' you could use some SNTP time servers but can't be sure port will be open
' or you could just ping your own webserver
Dim myNetRequest As WebRequest = HttpWebRequest.Create("http://www.example.com")
' read response header from connection
Dim response = myNetRequest.GetResponse()
' read date/time header
' assume its UTC format
Dim GlobalUTC As String = response.Headers("date").ToString
' convert string to datetime object
Dim parsedDateTime As DateTime = DateTime.Parse(GlobalUTC)
' get UNIX time stamp
Dim unixTime = (parsedDateTime - New DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds
Return unixTime
End Function
End Class
要测试输出,您可以添加:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim utc As String = GetNetTime.GetUTC
' add random alpha prefix to UNIX time stamp
Dim sPrefix As String = ""
Dim rdm As New Random()
For i As Integer = 1 To 3 ' if you need more than 3 alpah random charachters adjust i length
sPrefix &= ChrW(rdm.Next(65, 90))
Next
MsgBox(sPrefix & utc) ' OR MsgBox("ID" & sPrefix & utc)
' code here to use result
End Sub
我觉得这个解决方案比查询SQL表和读取最后一个记录id更有用,并且会增加。
备注:
输出示例:
GYK1501270543
VWT1501270606
WRH1501270634
SKI1501270648
QXL1501270716
答案 3 :(得分:0)
这也基于上面的@wpcoder答案,但是是一种基本形式,这对我有用
Public Function UIDGen(ByRef f As String) As String
Dim currentTime As DateTime = DateTime.UtcNow
Dim StringTime As String = currentTime.ToString
Dim parsedDateTime As DateTime = DateTime.Parse(StringTime)
Dim unixTime = (parsedDateTime - New DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds
Dim utcString As String = unixTime.ToString
Dim sPrefix As String = ""
Dim rdm As New Random()
For i As Integer = 1 To 3 ' 3 Letters enough ?
sPrefix &= ChrW(rdm.Next(65, 90))
Next
f = (sPrefix & utcString)
Return f
End Function