天天看點

DB4O在Windows phone 7和Silverlight中運用補充

<a href="http://blog.51cto.com/attachment/201201/230040721.jpg" target="_blank"></a>

解壓檔案後 發現在解壓路徑下可以看到db4o-net40\db4o-8.0\bin中多了Silverlight-3.0檔案夾:

<a href="http://blog.51cto.com/attachment/201201/230056277.jpg" target="_blank"></a>

建立一個WP7測試程式DB4oForW7p_Demo,對DB4O下Silverlight-3.0檔案夾下加以DLL引用 引用結果:

<a href="http://blog.51cto.com/attachment/201201/230114768.jpg" target="_blank"></a>

對于引用DB4O Silverlighti-3.0檔案夾DLL進行一下說明:

Cecil.Flowanalysis.dll —針對位元組碼分析庫原生查詢優化.

Db4objects.Db4o.dll — db4o資料庫引擎[核心]

Db4objects.Db4o.Linq.dll — LINQ查詢的支援

Db4objects.Db4o.Optional.dll —db4o的可選元件

建構一個簡單頁面: 直接測試WP7是否對DB4O加以支援:

<a href="http://blog.51cto.com/attachment/201201/230122583.jpg" target="_blank"></a>

引用完成後上次 對DB4O通路問題主要出現在無法建立DB4O資料庫檔案或是采取通路出現異常.類似我們這樣直接建立一個DB4O檔案:

//Create DB4O File DAtabase

string filepath = @"test.db4o";

IObjectContainer getdb40 = Db4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(), filepath);

這時會提示:嘗試通路操作通路檔案出現未處理異常.

System.MethodAccessException was unhandled 

Message=Attempt to access the method failed: System.IO.Path.GetFullPath(System.String) 

StackTrace: 

at Sharpen.IO.File.GetCanonicalPath() 

at Db4objects.Db4o.IO.FileStorage.FileBin..ctor(BinConfiguration config) 

at Db4objects.Db4o.IO.FileStorage.Open(BinConfiguration config) 

at Db4objects.Db4o.IO.StorageDecorator.Open(BinConfiguration config)

這個問題原因主要因為Silverlight 沙箱設計引起安全的,DB4O官方給出解釋是需要在對Silverlight情況進行獨立配置. 把資料庫檔案test.db4O進行隔離存儲來實作. 具體配置如下:

using Db4objects.Db4o;

using Db4objects.Db4o.Query;

using Db4objects.Db4o.Linq;

using Db4objects.Db4o.Config;

using Db4objects.Db4o.IO;

//Create new DB4o File Support.

IEmbeddedConfiguration configuration = Db4oEmbedded.NewConfiguration();

configuration.File.Storage = new IsolatedStorageStorage();

IObjectContainer getdb40 = Db4oEmbedded.OpenFile(configuration, filepath);

這時我們需要對IEmbeddedConfiguration進行特定配置, 即采用獨立存儲方式寫入DB4O資料庫檔案. 在Silverlight和WP7程式中這是必須的.另外對于上次JackLin提出無法再Xap固定資料庫檔案問題. 我嘗試另外一種辦法來解決這個問題:

我們可以把建立資料庫檔案test.DB4O以全局成員變量定義在App.Xaml.cs檔案,對于該程式所有頁面Test.DB4O資料庫檔案都是可見的. 但這麼做在WP7測試發現一個問題. 這樣配置成功之後, 從一個頁面跳轉到另一個頁面時 從新打開TEst.DB4O資料庫檔案進行資料通路時會提示一個異常:

Db4objects.Db4o.Ext.Db4oRecoverableException was unhandled

Message=Db4oRecoverableException

StackTrace:

at Db4objects.Db4o.Internal.ObjectContainerBase.GetByID(Transaction ta, Int64 id)

at Db4objects.Db4o.Internal.Fileheader.FileHeaderVariablePart.ReadIdentity(LocalTransaction trans)

at Db4objects.Db4o.Internal.Fileheader.NewFileHeaderBase.ReadIdentity(LocalObjectContainer container)

這時一個ReCoverableException.目前官方對于這個異常我沒有找到相關說法. ok. 建立TESt.DB4o檔案成功後建立一個實體類來直接儲存資料對象 如果我們這樣定義:

/// &lt;summary&gt;

/// use Data Model ProductCode EntityMode

/// Sign by chenkai Date:2010年10月19日11:21:02

/// &lt;/summary&gt;

public class ProductCode

{

public string CodeId { get; set; }

public string CodeName{get;set;}

public string CodeState{get;set;}

public string CodeDate{get;set;}

}

當我們建立一個ProductCode對象并儲存時 會提示一個異常:

MessageBox.Show("open file!");

//Create new ProductCode Entity Model

EntityModel.ProductCode newcode = new EntityModel.ProductCode { CodeId="0458", CodeName="SAP_BarCode", CodeState="check_In",CodeDate=DateTime.Now.ToString() };

getdb40.Store(newcode);

//Dispose the reasource

getdb40.Close();

getdb40.Dispose();

MessageBox.Show("save sucess!");

當執行到Stroe()存儲方法時會提示: “無法通路讀取目标對象的屬性”.截圖InnerException:

<a href="http://blog.51cto.com/attachment/201201/230130409.jpg" target="_blank"></a>

也就是在存儲資料時ProductCode實體的屬性字段. 這個問題是因為Silverlight為了保證程式的部署和通路安全程式運作在沙箱中.導緻私有字段無法存儲 對屬性字段通路不直接加以支援. 同時從類到成員對象必須是Public類型. 官方DB4O對Silverlight這種設計表态也是沒有辦法. 隻是聲明不斷盡力改善, 但可以把屬性類定義成另外一種方式:

public class ProductCode     

{     

public string CodeId;     

public string CodeName;     

public string CodeState;     

public string CodeDate;     

或是手寫定義屬性:

public string CodeName     

get { return codename; }     

set { codename = value;     

NotifyPropertyChanged("CodeName");     

}     

在引用中引入了Db4objects.Db4o.Linq.dll — LINQ查詢的支援. DB4O官方也聲明支援WP7. Linq查詢.但是後來我在編寫WP7批量處理資料采用Linq方式 例如:

//執行Linq查詢       

var q = from myproductcode getcode in app.db      

where getcode.ObjectID == oid and Codename="chenkaiCode"     

select getcode; 

偶爾程式會自動報出一個異常:

System.MissingMethodException was unhandled

Message=Method not found: quality rlib, Version=3.7.0.0, Culture=neutral, PublicKeyToken=969DB8053D3322AC.System.Type.

at JournalIt.JournalEntryListPage.PhoneApplicationPage_Loaded(Object sender, RoutedEventArgs e)

at System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)

at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)

Linq在WP7展現極為不穩定. 在項目中已經放棄使用DB4O對Linq資料處理支援.另外一個很情況是 引用了DB4O 後執行WP7 程式調試時, 程式執行無法找到指定斷點進行跟蹤調試.而是程式中直接作為一個UnHandle Exception 交給了Application_UnhandledException方法直接處理 斷開異常調試 很怪異啊 App.Xaml.CS 檔案Application_UnhandledException 方法:

// Code to execute on Unhandled Exceptions     

private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)     

if (System.Diagnostics.Debugger.IsAttached)     

// An unhandled exception has occurred; break into the debugger     

System.Diagnostics.Debugger.Break();     

//you get out the Mainpage  ???? why ?    

//sign by chenkai     

MessageBox.Show("you get ou t! by UnhandleException");    

 }    

很怪異啊.

<a href="http://blog.51cto.com/attachment/201201/230139642.jpg" target="_blank"></a>

DB4O如果作為WP7嵌入式開發本地資料庫 遇到各個方面問題遠遠超過我的預期. 

試用DB4O後 總結一下DB4O作為WP7嵌入式本地資料庫幾個特點:

&lt;1&gt;第一點是不得不說的是DB4O在Wp7需要額外的配置.一方面源于WP7基于Silverlight. SL平台為了應用程式運作和部署基于沙箱的設計 導緻每次方位DB4O都需要額外的配置成獨立存儲模式.

&lt;2&gt;不穩定性.我隻是測試DB4O7.2 For 3.5 和最新版本的8.0. 在程式配置後 出現無法調試. 對實體類私有字段屬性的通路限制. 以及Linq查詢對資料處理帶來幾乎是怪異的異常. 都讓我覺得在Wp7中把DB4O作為資料存儲是一件很累的事. 起碼這種異常讓我覺得編碼時異常反感. 同時覺得對程式來說不可靠.

&lt;3&gt; 不支援DB4O的Client/Server模式. 本來DB4O這個伺服器/用戶端設計是其他開源資料庫極為少見的. 本來打算10月1前就驗證一下DB4O這種工作原理.可惜的是WP7基于SL的特點.導緻Silverlight不容許直接的socket連接配接,至少使用db4o目前的執行情況,是不可能支援CS模式[新版本已經開始支援], 實際上Silverlight支援用戶端套接字隻是有些限制. 沒辦 隻能把DB4O測試放到Winform測試 SL平台是沒有指望了.

&lt;4&gt;非泛型類型缺乏. 在DB4O表現很嚴重. 作為一個開源項目DB4O是從Java移植成.NET版本的.特别對于SL平台 簡單檢視一下API 在IO操作和非泛型集合上變化比較大. 大部分集合是非泛型的,IO的操作采用資料存儲時基于SL的獨立存儲. 看來實質還沒變. [新版本正在改善.]

當然這隻是聲明我嘗試DB4O作為本地資料庫實作WP7通路遇到種種情況. 當然DB4O也有很出衆的特色.特别值得一提的是對實體對象直接存儲. 本來我在用之前一直很懷疑. 想想自己以前用Nhibernate來處理OO與關系型資料之間資料映射. DB4O面向 對象 我一直懷疑它是嵌入式資料庫在性能上一定不是太好.從官方釋出的測試資料來看 基本滿足需求.

<a href="http://blog.51cto.com/attachment/201201/230148484.jpg" target="_blank"></a>

針對個人使用DB4O在WP7上一些探索中.碰到一些問題. 當然是個人之見 其實寫這篇文章是一個很糾結過程. 因為描述大多是出現問題. DB4O面前新版已經SL3. 新版本不斷開發更新中. 但是如果真的把DB4O作為WP7 我認為 真的是很折磨人一件事. DB4o因為SL平台特殊性. 其本身固然存在一些問題.

另外一個原因 是 DB4o雖然是開源免費. 但是這照成一個開源項目特點. 對于問題更新和解決周期時間過長. 最為關鍵的是DB4O官方也聲明 既然為開源項目 它的更新和研發來自于開源社群不斷推動. 至于是否保持對SL平台的支援 還有待以後的觀望. DB4o對SL支援前景是不明确的.

如果說個人研究我覺得對于開源的DB4O來說還是很有意義的. 但是如果說真的投入商業性開發 或是企業級. 真的目前DB4O特點時不具備 我建議的不适用. 減少問題的出現.

本篇算是對DB4o在WP7結貼篇幅.

本文轉自chenkaiunion 51CTO部落格,原文連結:http://blog.51cto.com/chenkai/764478