在构造函数中自动生成唯一ID

Dia*_*ana 4 vb.net constructor

使用VB.net,创建一个名为staff的新类,它有三个属性:Name,LastName,ID - 应该适合用作数据库中的主键.

提供一个类构造函数来填充Name和LastName.ID应该在构造函数中自动生成,不应该传入.

我知道如何创建类,属性和构造函数,我只需要知道如何在构造函数中自动生成ID字段.是否有可能做到这一点?

我通常做的是将数据库中的id字段作为标识字段和主键,以便自动插入下一个可用的id或在我的应用程序中,我从数据库中读取最后一个ID并向其中添加一个ID.但我需要知道如何在构造函数中自动生成ID字段.

Adr*_*tti 6

GUID

如果您对ID类型没有任何约束,可以使用GUID:

Dim id As Guid = Guid.NewGuid()
Run Code Online (Sandbox Code Playgroud)

您甚至可以将其保留为字符串:

Dim id As String = Guid.NewGuid().ToString("N")
Run Code Online (Sandbox Code Playgroud)

应该授予它在不同机器上的唯一性(以满足您的要求,即它必须适合用作数据库中的主键).另见这篇文章.

时间戳

更糟糕的是,如果您没有这样严格的要求(网络中的唯一性),您可以使用时间戳.当然,在这种情况下,您必须考虑更多问题:

  • 法定时间:每年时间往返两次.
  • 区域:如果用户在伦敦输入数据然后他移居纽约怎么办?
  • 并发:您必须假设没有其他人向您的数据库添加记录(如果他们使用不同的技术,您可能会发生冲突).如果执行是并发的(程序的多个实例一起运行),也不能应用它.
  • 计时器粒度:系统日期具有粗粒度:如果在短时间内构造许多对象,则可能具有重复的ID.这篇文章中的解决方法.

计数器

如果满足所有这些条件:

  • 应用程序的多个实例不会并行运行.
  • 你正在使用一台计算机(而不是网络).
  • 每次应用程序启动时,数据库都为空.

Shared每次构造新对象时,您都可以使用计数器递增.如果系统计时器粒度不是问题(请参阅有关时间戳的段落),则可以将系统运行时间用作ID.由于粒度的限制,即使同时运行同一应用程序的多个实例,它也应该有效.

如果使用Shared字段,则必须处理同步问题.如本评论中所述,您可以使用SyncLock.作为替代方案,您可以使用Interlocked.Increment操作.

哈希码

如果计数器的所有条件都满足,那么这个也是:

  • 你的应用程序是32位.
  • 您的对象不是a ValueType,它不会覆盖GetHashCode()方法.

您可以使用哈希码(获取GetHashCode())因为(来自MSDN):

换句话说,ReferenceEquals方法返回true的两个对象具有相同的哈希码.

因为只有在比较同一实例时Object.ReferenceEquals()返回,true所以每个实例都将具有唯一的哈希代码(因为在32位应用程序中哈希代码是对象引用本身).请注意,这是一个实现细节,可能会发生变化.

随机数

我知道这可能会让某人感到震惊,但64位值的好随机数生成器的碰撞概率非常低.我重复的概率非常低(有关更多数学详细信息,请参阅此文章).只是不要System.Random用于此!

根据您使用的种子,您也可以在网络场景中生成随机数(不要忘记 - 需要引用 - 一个本地网络协议的早期草案提出了一个32位随机数作为地址,它已被更改,因为来自用户的不良反馈,但这并不意味着它无法工作).