儲存結構化的物件
如同儲存一般物件一樣,我們也是呼叫 Set() 方法來儲存 Article 物件。與 Article 物件關連的 Sentence 物件會被自動儲存!string pmid = "123"; string title = "sent0"; Article article = new Article(pmid, title); List上面的程式碼相當於我們手動將各物件存入資料庫:abs=new List (); abs.Add(new Sentence("sent1","METHOD")); abs.Add(new Sentence("sent2","METHOD")); abs.Add(new Sentence("sent3","CONCLUSION")); article.SentencesOfAbstract=abs; db.Set(article);
Listabs=new List (); abs.Add(new Sentence("sent1","METHOD")); abs.Add(new Sentence("sent2","METHOD")); abs.Add(new Sentence("sent3","CONCLUSION")); db.Set(abs); string pmid = "123"; string title = "sent0"; Article article = new Article(pmid, title); article.SentencesOfAbstract=abs; db.Set(article);
取回結構化物件
QBE
要取回所有的 Article 物件,我們跟以前一樣,只要提供一個空的 prototype 即可:Article proto = new Article(null,null); IObjectSet result = db.Get(proto); ListResult(result);當然,我也可以取回所有的 Sentence 物件!
Sentence proto = new Sentence(null,null); IObjectSet result = db.Get(proto); ListResult(result);我們也可以取得所有 Article 物件中滿足 section 為 TITLE 的 Sentence 物件:
Sentence title = new Sentence(null,"TITLE"); Article article = new Article(null,title); IObjectSet result = db.Get(article); ListResult(result);
Native Queries
對結構化物件使用 Native Query 跟一般物件幾乎一模一樣。下面示範如何取回 一群 Article 物件,使其 Title Sentence 滿足指定的參數:/// C# .NET 1.1 public class RetrieveArticlesByTitlePredicate : Predicate { readonly string _title; public RetrieveArticlesByTitlePredicate(string title) { _title = title; } public bool Match(Article candidate) { return candidate.SentenceOfTitle.RawText == _title; } } // 使用方法 string title = "sent0"; IObjectSet results = db.Query(new RetrieveArticlesByTitlePredicate(title)); ListResult(results); /// C# .NET 2.0 string title = "sent0"; Listresults = db.Query (delegate(Article article) { return article.SentenceOfTitle.RawText == title; }); listResults(results);
SODA Query API
使用 SODA 的話,必須 descend 兩次以便取得 rawText:IQuery query = db.Query(); query.Constrain(typeof(Article)); query.Descend("title").Descend("rawText") .Constrain("sent0"); IObjectSet result = query.Execute(); ListResult(result);另外,我們也可以藉由指定 SentenceOfTitle 欄位來達到相同的效果:
IQuery query = db.Query(); query.Constrain(typeof(Sentence)); Sentence proto = new Sentence("sent0", null); query.Descend("title").Constrain(proto); IObjectSet result = query.Execute(); ListResult(result);下面我們示範如何取得所有 PMID 為 123 的 SentencesOfAbstract 欄位:
IQuery artQuery = db.Query(); artQuery.Constrain(typeof(Article)); artQuery.Descend("pmid").Constrain("123"); IQuery sentQuery = artQuery.Descend("_SentencesOfAbs"); IObjectSet result = sentQuery.Execute(); ListResult(result);
更新結構化物件
如同一般物件一般,要更新結構化物件,也是對它們再次呼叫 Set() 方法:IObjectSet result = db.Get(new Article("123",null)); Article found = (Article)result.Next(); found.SentenceOfTitle = new Sentence("sentXYZ",null); db.Set(found);下面我們嘗試直接更新 SentenceOfAbstract 物件內容:
IObjectSet result = db.Get(new Article("123",null)); Article found = (Article)result.Next(); List看起來似乎一切都很簡單、美好?但是實際上,若是我們再度存取資料庫,檢查我們的更新:abs=new List (); abs.Add(new Sentence("sent1","INTRODUCTION")); abs.Add(new Sentence("sent2","METHOD")); abs.Add(new Sentence("sent3","CONCLUSION")); found.SentenceOfAbstract=abs; db.Set(found);
result = db.Get(new Article("123",null)); ListResult(result);我們會發現,更新並未成功!這是因為效能上的考量,db4o 不會自動的更新結構化物件內的所有成員類別!為了兼顧效能與程式碼撰寫的簡潔,db4o 導入了 update depth 的概念,來控制程式在更新時,物件成員樹的更新深度。
update depth
對於所有的物件而言,預設的 update depth 是 1,代表只有 primitive 以及 String 成員會被更新。
db4o 提供了相當精細的方法來控制 update depth。下面我們藉由設定 CascadeOnUpdate 為 true,指定 db4o 完整的更新 Article 物件的內容:
Db4oFactory.Configure().ObjectClass(typeof(Article)) .CascadeOnUpdate(true); // 接下來才去設定 Article 物件內容要注意的地方是,先設定好 update depth 後才去更新才有效。
刪除結構化物件
一樣,用 Delete() 方法即可:IObjectSet result = db.Get(new Article("123",null)); Article found = (Article)result.Next(); db.Delete(found); result = db.Get(new Car(null));我們應該會認為 db4o 應該也會把 Article 物件內一堆的 Sentence 物件也刪除了吧?但是實際上, db4o 並不會幫我們做這件事!
遞迴刪除結構化物件內成員
跟更新時一樣,我們可以設定 db4o,幫我們完成這件事:Db4oFactory.Configure().ObjectClass(typeof(Article)) .CascadeOnDelete(true); // 接下來才去刪掉 // ...另外要注意的一點是,目前的 db4o 版本(6.0)中,就算我們要刪除的資料庫物件,目前仍然被程式內的變數參考到,它們經由遞迴刪除後,一樣會被從資料庫內移除。
1 則留言:
關於 update depth 的部分:CascadeOnUpdate 的設定必須要在資料庫開啟前就設定好了!
張貼留言