最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于C#生成MongoDB中ObjectId的實現(xiàn)方法

 更新時間:2013年04月24日 09:46:16   作者:  
本篇文章小編為大家介紹,關(guān)于C#生成MongoDB中ObjectId的實現(xiàn)方法。需要的朋友參考下

ObjectId介紹
在MongoDB中,文檔(document)在集合(collection)中的存儲需要一個唯一的_id字段作為主鍵。這個_id默認(rèn)使用ObjectId來定義,因為ObjectId定義的足夠短小,并盡最大可能的保持唯一性,同時能被快速的生成。

ObjectId 是一個 12 Bytes 的 BSON 類型,其包含
1.4 Bytes 自紀(jì)元時間開始的秒數(shù)
2.3 Bytes 機器描述符
3.2 Bytes 進(jìn)程ID
4.3 Bytes 隨機數(shù)

從定義可以看出,在同一秒內(nèi),在不同的機器上相同進(jìn)程ID條件下,非常有可能生成相同的ObjectId。
同時可以根據(jù)定義判斷出,在給定條件下,ObjectId本身即可描述生成的時間順序

ObjectId的存儲使用Byte數(shù)組,而其展現(xiàn)需將Byte數(shù)組轉(zhuǎn)換成字符串進(jìn)行顯示,所以通常我們看到的ObjectId都類似于:

ObjectId("507f191e810c19729de860ea")

C#定義ObjectId類

復(fù)制代碼 代碼如下:

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
     {
       get { 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#實現(xiàn)ObjectId的生成器
復(fù)制代碼 代碼如下:

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++;
       }
     }
   }

使用舉例
復(fù)制代碼 代碼如下:

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();
     }
   }


 

相關(guān)文章

最新評論

南木林县| 句容市| 陇西县| 永胜县| 五华县| 金秀| 铁力市| 宜春市| 乌苏市| 维西| 桓仁| 珲春市| 四会市| 柘城县| 通榆县| 敦煌市| 永靖县| 平塘县| 南木林县| 文昌市| 咸阳市| 安陆市| 蚌埠市| 鄂托克旗| 山阳县| 广州市| 河津市| 綦江县| 固镇县| 灵丘县| 新蔡县| 正镶白旗| 岑溪市| 乌兰察布市| 南漳县| 景宁| 舞钢市| 开封县| 旅游| 临朐县| 秀山|