DB4O設(shè)置自增ID的方法詳解
DB4O是一種開源的純面向?qū)ο蟮臄?shù)據(jù)庫(kù)引擎,它帶給了我們***的ORM體驗(yàn):
- 直接存儲(chǔ)對(duì)象
- 直接查詢, 更新, 刪除對(duì)象
- 直接支持LINQ
- 無(wú)需創(chuàng)建表結(jié)構(gòu), 更無(wú)需維護(hù)數(shù)據(jù)庫(kù)
- 超小的數(shù)據(jù)庫(kù)引擎, 不到800KB
- 原生支持C#和JAVA
- 性能高效
而我們?cè)谑褂玫倪^(guò)程中常常需要設(shè)置自增ID,那么如何設(shè)置呢?接下來(lái)我們就開始介紹。
為對(duì)象增加自增ID
解決方案:
- Book book = new Book();
- book.Id = ?;
- Db4oFactory.OpenFile("Data.dat").Store(book);
DB4O手冊(cè)上說(shuō), 不推薦對(duì)象使用Id屬性, 但這明顯是對(duì)這個(gè)問(wèn)題的回避:
對(duì)某些數(shù)據(jù)應(yīng)用而言, 如訂單, 流水線等, 自增Id是必不可少的, 此時(shí),如果采用DB4O作存儲(chǔ)的話:
1. 不得不手動(dòng)查詢得到當(dāng)前***Id然后持久化;
2. 對(duì)于復(fù)雜對(duì)象而言, 則需要遞歸檢查,確保每一級(jí)子對(duì)象自增Id都設(shè)置正確。。。這個(gè)是讓人難以接受的。
另一種解決方案:
1. 在DB4O中存儲(chǔ)一組 (類型 =>NextId) 對(duì)象, 用來(lái)保存每種持久化對(duì)象的Type和該類型的下一個(gè)自增Id值.
- /// <summary>
- /// 內(nèi)部存儲(chǔ)使用, 保存每一種類型對(duì)象的***一個(gè)自增Id
- /// </summary>
- class SerialIdEntity
- {
- public Type ObjectType { get; set; }
- public int NextId { get; set; }
- }
2. 用Attribute來(lái)標(biāo)記對(duì)象的Id自增屬性.
- class SerialIdAttribute : Attribute
- {
- }
- class Book
- {
- [SerialId()]
- public int Id
- {
- get; set;
- }
- }
3. 持久化時(shí)反射檢查屬性是否有SerialIdAttribute, 若存在則先取出此類型的下一個(gè)自增Id, 并自增其類型對(duì)應(yīng)的NextId, 然后存儲(chǔ).
- /// <summary>
- /// 保存對(duì)象: 檢查自增字段
- /// </summary>
- /// <param name="?"></param>
- public static void Add(object obj)
- {
- Type t = obj.GetType();
- foreach (var p in t.GetProperties())
- {
- #region 自增屬性
- SerialIdAttribute[] ids = (SerialIdAttribute[]p.GetCustomAttributes(typeof(SerialIdAttribute), false);
- if (ids.Length > 0)
- {
- SerialIdAttribute id = ids[ids.Length - 1];
- p.SetValue(obj, GenerateNexId(t), null);
- }
- #endregion
- #region 關(guān)聯(lián)子對(duì)象(含自增屬性)
- //遞歸遍歷子對(duì)象
- object subObj = p.GetValue(obj, null);
- //...
- #endregion
- }
- Db4oFactory.OpenFile("Data.dat").Store(obj);
- }
- private static int GenerateNexId(Type t)
- {
- SerialIdEntity sid;
- var res = from so in Db4oFactory.OpenFile("Data.dat").Query<SerialIdEntity>()
- where so.ObjectType == t
- select so;
- List<SerialIdEntity> data = res.ToList();
- if (data.Count > 0)
- {
- sid = data[0];
- }
- else
- {
- sid = new SerialIdEntity(){ ObjectType = t };
- }
- sid.NextId++;
- Db4oFactory.OpenFile("Data.dat").Store(sid);
- return sid.NextId;
- }
同樣的問(wèn)題:
對(duì)復(fù)雜對(duì)象而言, 對(duì)象中關(guān)聯(lián)子對(duì)象, 存儲(chǔ)時(shí)需要遞歸遍歷檢查自己的屬性及子對(duì)象的屬性.DB4O中的ID SYSTEM有兩種. 一個(gè)是物理ID(即指向?qū)ο箸R像存儲(chǔ)位置的指針), 一個(gè)是UUID(需要在創(chuàng)建數(shù)據(jù)庫(kù)時(shí)指定配置項(xiàng)), 都與自增無(wú)關(guān)。
關(guān)于DB4O設(shè)置自增ID的方法就介紹到這里了,希望本次的介紹能夠?qū)δ兴斋@!
【編輯推薦】






