MongoDB Long/Int(長整型)的自增長主鍵 解決方案


今朝有幸嘗芒果,發現自增長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 }
View Code

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM