How to generate ObjectId in MongoDB in C #

Source: Internet
Author: User
Tags epoch time

ObjectId Introduction
In MongoDB, a unique _ id field is required to store documents in collections as the primary key. By default, ObjectId is used to define the _ id, because the definition of ObjectId is short enough to maintain uniqueness as much as possible and can be quickly generated.

ObjectId is a 12 Bytes BSON type, which contains:
1.4 Bytes: the number of seconds since the epoch time
2.3 Bytes machine Descriptor
3.2 Bytes process ID
4.3 Bytes Random Number

It can be seen from the definition that the same ObjectId may be generated under the same process ID condition on different machines within the same second.
At the same time, it can be determined according to the definition that under the given conditions, ObjectId itself can describe the generated time sequence.

The storage of ObjectId uses a Byte array, and its display needs to convert the Byte array to a string for display. Therefore, the ObjectId we usually see is similar:

ObjectId ("507f191e810c19729de860ea ")

C # define the ObjectId class

Copy codeThe Code is as follows: View Code
Public class ObjectId
{
Private string _ string;

Public ObjectId ()
{
}

Public ObjectId (string value)
: This (DecodeHex (value ))
{
}

Internal ObjectId (byte [] value)
{
Value = value;
}

Public static ObjectId Empty
{
Obtain {return new ObjectId ("000000000000000000000000 ");}
}

Public byte [] Value {get; private set ;}

Public static ObjectId NewObjectId ()
{
Return new ObjectId {Value = ObjectIdGenerator. Generate ()};
}

Public static bool TryParse (string value, out ObjectId objectId)
{
ObjectId = Empty;
If (value = null | value. Length! = 24)
{
Return false;
}

Try
{
ObjectId = new ObjectId (value );
Return true;
}
Catch (FormatException)
{
Return false;
}
}

Protected static byte [] DecodeHex (string value)
{
If (string. IsNullOrEmpty (value ))
Throw new ArgumentNullException ("value ");

Var chars = value. ToCharArray ();
Var numberChars = chars. Length;
Var bytes = new byte [numberChars/2];

For (var I = 0; I <numberChars; I + = 2)
{
Bytes [I/2] = Convert. ToByte (new string (chars, I, 2), 16 );
}

Return bytes;
}

Public override int GetHashCode ()
{
Return Value! = Null? ToString (). GetHashCode (): 0;
}

Public override string ToString ()
{
If (_ string = null & Value! = Null)
{
_ String = BitConverter. ToString (Value)
. Replace ("-", string. Empty)
. ToLowerInvariant ();
}

Return _ string;
}

Public override bool Equals (object obj)
{
Var other = obj as ObjectId;
Return Equals (other );
}

Public bool Equals (ObjectId other)
{
Return other! = Null & ToString () = other. ToString ();
}

Public static implicit operator string (ObjectId objectId)
{
Return objectId = null? Null: objectId. ToString ();
}

Public static implicit operator ObjectId (string value)
{
Return new ObjectId (value );
}

Public static bool operator = (ObjectId left, ObjectId right)
{
If (ReferenceEquals (left, right ))
{
Return true;
}

If (object) left = null) | (object) right = null ))
{
Return false;
}

Return left. Equals (right );
}

Public static bool operator! = (ObjectId left, ObjectId right)
{
Return! (Left = right );
}
}

C # ObjectId Generator
Copy codeThe Code is as follows: View Code
Internal static class ObjectIdGenerator
{
Private static readonly DateTime Epoch =
New DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind. Utc );
Private static readonly object _ innerLock = new object ();
Private static int _ counter;
Private static readonly byte [] _ machineHash = GenerateHostHash ();
Private static readonly byte [] _ processId =
BitConverter. GetBytes (GenerateProcessId ());

Public static byte [] Generate ()
{
Var oid = new byte [12];
Var copyidx = 0;

Array. Copy (BitConverter. GetBytes (GenerateTime (), 0, oid, copyidx, 4 );
Copyidx + = 4;

Array. Copy (_ machineHash, 0, oid, copyidx, 3 );
Copyidx + = 3;

Array. Copy (_ processId, 0, oid, copyidx, 2 );
Copyidx + = 2;

Array. Copy (BitConverter. GetBytes (GenerateCounter (), 0, oid, copyidx, 3 );

Return oid;
}

Private static int GenerateTime ()
{
Var now = DateTime. UtcNow;
Var nowtime = new DateTime (Epoch. Year, Epoch. Month, Epoch. Day,
Now. Hour, now. Minute, now. Second, now. Millisecond );
Var diff = nowtime-Epoch;
Return Convert. ToInt32 (Math. Floor (diff. TotalMilliseconds ));
}

Private static byte [] GenerateHostHash ()
{
Using (var md5 = MD5.Create ())
{
Var host = Dns. GetHostName ();
Return md5.ComputeHash (Encoding. Default. GetBytes (host ));
}
}

Private static int GenerateProcessId ()
{
Var process = Process. GetCurrentProcess ();
Return process. Id;
}

Private static int GenerateCounter ()
{
Lock (_ innerLock)
{
Return _ counter ++;
}
}
}

Example
Copy codeThe Code is as follows: class Program
{
Static void Main (string [] args)
{
Console. ForegroundColor = ConsoleColor. Red;

ObjectId emptyOid = ObjectId. Empty;
Console. WriteLine (emptyOid );

Console. WriteLine ();
Console. ForegroundColor = ConsoleColor. Green;

For (int I = 0; I <10; I ++)
{
ObjectId oid = ObjectId. NewObjectId ();
Console. WriteLine (oid );
}

Console. WriteLine ();
Console. ForegroundColor = ConsoleColor. Blue;

ObjectId existingOid;
ObjectId. TryParse ("507f191e810c19729de860ea", out existingOid );
Console. WriteLine (existingOid );

Console. ReadKey ();
}
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.