Name,LastName,ID – 应该适合用作数据库中的主键.
提供一个类构造函数来填充Name和LastName. ID应该在构造函数中自动生成,不应该传入.
我知道如何创建类,属性和构造函数,我只需要知道如何在构造函数中自动生成ID字段.是否有可能做到这一点?
我通常做的是将数据库中的id字段作为标识字段和主键,以便自动插入下一个可用的id或在我的应用程序中,我从数据库中读取最后一个ID并向其中添加一个ID.但我需要知道如何在构造函数中自动生成ID字段.
GUID如果您对ID类型没有任何约束,可以使用GUID:
Dim id As Guid = Guid.NewGuid()
您甚至可以将其保留为字符串:
Dim id As String = Guid.NewGuid().ToString("N")
应该授予它在不同机器上的唯一性(以满足您的要求,即它必须适合用作数据库中的主键).另见this post.
时间戳
更糟糕的是,如果您没有这样严格的要求(网络中的唯一性),您可以使用时间戳.当然,在这种情况下,您必须考虑更多问题:
>法定时间:每年时间往返两次.
>区域:如果用户在伦敦输入数据然后他移居纽约怎么办?
>并发:您必须假设没有其他人向您的数据库添加记录(如果他们使用不同的技术,您可能会发生冲突).如果执行是并发的(程序的多个实例一起运行),也不能应用它.
>计时器粒度:系统日期具有粗粒度:如果您在短时间内构造了许多对象,那么您可能会有重复的ID. this post的解决方法.
计数器
如果满足所有这些条件:
>应用程序的多个实例不会并行运行.
>您正在使用单台计算机(而非网络).
>每次应用程序启动时,数据库都为空.
每次构造新对象时,您可以使用共享计数器递增.如果系统计时器粒度不是问题(请参阅有关时间戳的段落),则可以使用system up time作为ID.由于粒度的限制,即使同时运行同一应用程序的多个实例,它也应该有效.
如果您使用共享字段,则必须处理同步问题.如this comment所示,您可以使用SyncLock.作为替代方案,您可以使用Interlocked.Increment操作.
哈希码
如果计数器的所有条件都满足,那么这个也是:
>您的应用程序是32位.
>您的对象不是ValueType,它不会覆盖GetHashCode()方法.
您可以使用哈希码(使用GetHashCode()获取),因为(从MSDN开始):
In other words, two objects for which the ReferenceEquals method returns true have identical hash codes.
因为Object.ReferenceEquals()仅在比较同一实例时才返回true,因此每个实例将具有唯一的哈希代码(因为在32位应用程序中哈希代码是对象引用本身).请注意,这是一个实现细节,可能会发生变化.
随机数
我知道这可能会让某人感到震惊,但64位值的好随机数生成器的碰撞概率非常低.我重复的概率非常低(有关更多数学详细信息,请参阅this article).只是不要使用System.Random!
根据您使用的种子,您也可以在网络场景中生成随机数(不要忘记 – 需要引用 – 一个本地网络协议的早期草案提出了一个32位随机数作为地址,它已被更改,因为来自用户的不良反馈,但这并不意味着它无法工作).