Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto-generate Unique ID within the constructor

Using VB.net, create a new class called staff, with three properties: Name , LastName, ID - should be suitable for use as a primary key in a database.

Provide a class constructor to populate Name and LastName. ID should be auto-generated within the constructor and should not be passed in.

I know how to create a class, properties and constructor, I just need to know how to auto-generate ID field within the constructor. Is it possible to do this?

what I usually do is either make the id field in database as identity field and primary key so it automatically inserts the next available id or In my application I read the last ID from database and add one to it. But I need to know how to auto-generate ID field within the constructor.

like image 672
Diana Avatar asked Jan 29 '14 14:01

Diana


3 Answers

Guid

If you do not have any constrain about ID type you can use a GUID:

Dim id As Guid = Guid.NewGuid()

You may even keep it as string:

Dim id As String = Guid.NewGuid().ToString("N")

That should be granted to be unique across different machines (to satisfy your requirement that it has to be suitable for use as a primary key in a database). See also this post.

Timestamp

That was worse case, if you do not have such strict requirement (uniqueness across a network) you may use a timestamp. Of course, in this case, you have to consider more issues:

  • Legal time: time goes back and forward twice per year.
  • Zones: what if user enter data in London and then he moves to New York?
  • Concurrency: you have to assume no one else adds records to your database (you may have collisions if they use a different technique). Also you can't apply this if execution is concurrent (multiple instance of your program running together).
  • Timer granularity: system date has a coarse granularity: if you construct many objects in a short period of time then you may have duplicate IDs. Workaround in this post.

Counter

If all these conditions are satisfied:

  • Multiple instances of your application won't run in parallel.
  • You're working on a single computer (not a network).
  • Database is empty every time your application starts.

You may use a Shared counter incremented each time a new object is constructed. If system timer granularity isn't an issue (see paragraph about timestamp)you may use system up time as ID. With limitations about granularity it should work even with multiple instances of the same application running concurrently.

If you use a Shared field you have to deal with synchronization issues. As suggested in this comment you may use a SyncLock. As alternative you may use an Interlocked.Increment operation.

Hash code

If all condistions for a counter are satisfied and this one also:

  • Your application is 32 bit.
  • Your object is not a ValueType and it doesn't override GetHashCode() method.

You can use hash-code (obtained with GetHashCode()) because (from MSDN):

In other words, two objects for which the ReferenceEquals method returns true have identical hash codes.

Because Object.ReferenceEquals() returns true only if you compare same instance then each instance will have a unique hash code (because in a 32 bit application hash code is object reference itself). Be aware this is an implementation detail and it may change.

Random number

I know this may shock someone but a good random number generator for a 64 bit value has a very low probability of collisions. I repeat very very low probability (see this article for more math details). Just do not use System.Random for this!

According to which seed you use you may be able to generate random numbers in a network scenario too (do not forget - citation needed - that earlier drafts for one local network protocol proposed a 32 bit random number as address, it has been changed because of bad feedback from users but it doesn't mean it can't work).

like image 126
Adriano Repetti Avatar answered Oct 29 '22 22:10

Adriano Repetti


You want a number that won't repeat ever! So why not just use this?

    Dim dateAndTime As Date
    dateAndTime = Now
    TextBoxPID.Text = Format(dateAndTime, "yyyyMMddHHmmss").ToString

Unless your data entries are going to take place in milliseconds, this solution works great. If you are running into a millisecond issue then just add a counter to the end of the string.

    counter +=1
    TextBoxPID.Text = Format(dateAndTime, "yyyyMMddHHmmss").ToString & counter.ToString

If you are working on a network and have several people doing data entry then add their employee id to the string. There are easy solution to every issue, but in most, if not all cases, this will work without issue.

like image 31
Thurman Jenner Avatar answered Oct 29 '22 22:10

Thurman Jenner


Generate Random Unique User ID depending on SNTP server.

My requirements are a bit different; yet I needed to generate a random and unique User ID, that is 10 numbers, spending fair time couldn't find a suitable solution. so I ended up with the following function; its unique and random result.

As per one application instant on one test machine it is incremental unique result; because the user will generate the ten digits one time on a non pre-selective timestamp. In addition to playing with the random alpha prefix; I hope this function can provide a solution:

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

To test the output, you could add:

    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

I find this solution more useful than querying the SQL table and read last record id and do increment.

Notes:

  • Please don't mind long answer; as I tried to comment the code and explain the scenario in details.
  • I think this is good for generating UserID for application running on multiple workstations.
  • Please don't put the function in for ... loop or exhaust run it.

Output examples:

GYK1501270543

VWT1501270606

WRH1501270634

SKI1501270648

QXL1501270716
like image 1
wpcoder Avatar answered Oct 29 '22 20:10

wpcoder