源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

关于C#生成MongoDB中ObjectId的实现方法

  • 时间:2020-11-09 03:52 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:关于C#生成MongoDB中ObjectId的实现方法
[b]ObjectId介绍 [/b]在MongoDB中,文档(document)在集合(collection)中的存储需要一个唯一的_id字段作为主键。这个_id默认使用ObjectId来定义,因为ObjectId定义的足够短小,并尽最大可能的保持唯一性,同时能被快速的生成。 [b]ObjectId 是一个 12 Bytes 的 BSON 类型,其包含[/b]: 1.4 Bytes 自纪元时间开始的秒数 2.3 Bytes 机器描述符 3.2 Bytes 进程ID 4.3 Bytes 随机数 从定义可以看出,在同一秒内,在不同的机器上相同进程ID条件下,非常有可能生成相同的ObjectId。 同时可以根据定义判断出,在给定条件下,ObjectId本身即可描述生成的时间顺序 ObjectId的存储使用Byte数组,而其展现需将Byte数组转换成字符串进行显示,所以通常我们看到的ObjectId都类似于: [b]ObjectId("507f191e810c19729de860ea")[/b] [b]C#定义ObjectId类 [/b]
[u]复制代码[/u] 代码如下:
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);      }    }
[b]C#实现ObjectId的生成器 [/b]
[u]复制代码[/u] 代码如下:
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++;        }      }    }
[b]使用举例 [/b]
[u]复制代码[/u] 代码如下:
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();      }    }
[img]http://files.jb51.net/file_images/article/201304/2013042409370611.png[/img]  
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部