今朝有幸嘗芒果,發現自增長ID類型有多種,唯獨沒有Long/Int。
一思路:
1. 自建一個Collection(表,假設名為:IdentityEntity,其中字段:_id, Key, Value,其中_id你懂的,Key:Collection名,需要用Long/Int自增長主鍵的Collection名,value:Key字段中所存Collection的Long/Int自增長最大值),此表用於存入要用Long/Int自增長主鍵的Collection信息(為方便舉例:XLogs)
結構自建的Collection, IdentityEntity如下:
_id Key Value
new Guid() XLogs 5
2. 每次往XLogs新增數據時,將當前最大值(5)取出來,然后再加1,我們知道自增長鍵是無需我們明確Insert的,當然它也一樣整個過程都是由Mongo自身框架內部完成。
3. 既然是內部完成,我們就得實現一小部分代碼,讓Mongo框架來調用
二實現:
1. Mongo框架中的接口:IIdGenerator

1 #region 程序集 MongoDB.Bson.dll, v1.9.2.235 2 // E:\Projects\DLL\MongoDB.Bson.dll 3 #endregion 4 5 using System; 6 7 namespace MongoDB.Bson.Serialization 8 { 9 // 摘要: 10 // An interface implemented by Id generators. 11 public interface IIdGenerator 12 { 13 // 摘要: 14 // Generates an Id for a document. 15 // 16 // 參數: 17 // container: 18 // The container of the document (will be a MongoCollection when called from 19 // the C# driver). 20 // 21 // document: 22 // The document. 23 // 24 // 返回結果: 25 // An Id. 26 object GenerateId(object container, object document); 27 // 28 // 摘要: 29 // Tests whether an Id is empty. 30 // 31 // 參數: 32 // id: 33 // The Id. 34 // 35 // 返回結果: 36 // True if the Id is empty. 37 bool IsEmpty(object id); 38 } 39 }
2. 實現接口,代碼:
1 public class LongIdGenerator<TDocument, TKey> : IIdGenerator where TDocument : class 2 { 3 private static LongIdGenerator<TDocument, TKey> _instance = new LongIdGenerator<TDocument, TKey>(); 4 public static LongIdGenerator<TDocument, TKey> Instance { get { return _instance; } } 5 6 public object GenerateId(object container, object document) 7 { 8 TKey id = default(TKey); 9 var collection = container as MongoCollection<TDocument>; 10 if (null != collection) 11 { 12 var mongoDB = collection.Database; 13 var idColl = mongoDB.GetCollection<IdentityEntity<TKey>>("IdentityEntity"); 14 var keyName = document.GetType().Name; 15 id = RealGenerateId(idColl, keyName) ; 16 } 17 return id; 18 } 19 20 private TKey RealGenerateId(MongoCollection<IdentityEntity<TKey>> idColl, string keyName) 21 { 22 TKey id; 23 var idQuery = new QueryDocument("Key", BsonValue.Create(keyName)); 24 var idBuilder = new UpdateBuilder(); 25 idBuilder.Inc("Value", 1); 26 27 var args = new FindAndModifyArgs(); 28 args.Query = idQuery; 29 args.Update = idBuilder; 30 args.VersionReturned = FindAndModifyDocumentVersion.Modified; 31 args.Upsert = true; 32 33 var result = idColl.FindAndModify(args); 34 if (!string.IsNullOrEmpty(result.ErrorMessage)) 35 { 36 throw new Exception(result.ErrorMessage); 37 } 38 id = result.GetModifiedDocumentAs<IdentityEntity<TKey>>().Value; 39 return id; 40 } 41 42 public bool IsEmpty(object id) 43 { 44 if (null == id) 45 { 46 return false; 47 } 48 return true; 49 } 50 }
2.2. 從上代碼看我們知道,先要了解對Mongodb Collection的增,改,查等基本操作,然后理解“思路”中所提內容。注意Collection IdentityEntity在代碼中已寫死,當他不存在時第一次運行會自動新增此Collection。
三應用
到此已完成代碼實現。即然實現,那么開始談應用:
方式1.
1 public class XLogs : BaseLog, IEntity<long> 2 { 3 //應用:在long自增長鍵上加此特性 4 [BsonId(IdGenerator = typeof(LongIdGenerator<XLogs>))] 5 public long Id { get; set; } 6 7 public byte Status { get; set; } 8 9 public string CreatedBy { get; set; } 10 11 public System.DateTime CreatedDate { get; set; } 12 13 public string Remark { get; set; } 14 15 public decimal Amount { get; set; } 16 }
方式2. 注冊的方式,在數據進Collection XLogs之前,就要運行它
1 BsonClassMap.RegisterClassMap<XLogs>(rc => 2 { 3 rc.AutoMap(); 4 rc.SetIdMember(rc.GetMemberMap(c => c.Id)); 5 rc.IdMemberMap.SetIdGenerator(LongIdGenerator<XLogs, long>.Instance); 6 });