今朝有幸尝芒果,发现自增长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 });
|