天天看點

多樣化實作Windows Phone 7本地資料庫通路<上>

最近個人的時間顯得比較緊迫,有一些想法一直沒有時間去驗證,上周五在MSDN上公布的活動Silverlight Events:與John Papa面對面學習Silverlight 4中因為一時疏忽趕到MSDN會客廳是活動已經結束了。 不過我順便看看活動中對JohnPapa提出問題: 其中有人明确提出Silverlight 下一版本會把本地資料庫通路支援是否會在下一個Silverlight版本加入?[可惜我沒有看到John Papa本人的回複],這突然讓我聯想到最近一直在看官方公布開源項目中Windows Phone 7對本地資料資料庫操作方式, 恰好上周我做了一個SQlite相關測試。 有意無意間讓我把Windows Phone 7 對本地資料庫Local DataBase通路與開源資料庫聯系在一起。如下是我個人對WP7本地資料庫通路方式的驗證,如有疑問請及時提出。

  Windows Phone 7在CTP 版本時微軟官方就對開發者提出問題做了兩次集體回應. 一次是在3月19日 另外一次是5月19日.回複内容詳見Windows Phone 7 Series Developer General FAQ (Updated 5/19/2010), 内容中包含了WP7開發中多個細節和下一步需要改善的方向等做了明确回複. 當然其中也包含了大家很關心的資料通路. 具體回應内容如下:

在Windows Phone 7 Series的裝置上有沒有本地資料庫可以利用? 

沒有,在最初的Windows Phone 7 Series上沒有本地資料庫API可以利用 

我應該如何為我的應用程式存儲資訊? 

你可以将資訊存儲在自己的存儲空間裡。如果你需要大型的資料庫這裡有一些選擇:Windows Phone 7 Seires 已經支援WebServices,它可以讓你容易的通路存儲在Internet上的資訊。使用一個可以被WebServices通路的資料庫,你的應用程式就可以在連接配接Internet的情況下實時的擷取資料.

以後會支援本地資料庫嗎? 

目前我們沒有宣告這樣的計劃來增加這一功能;但是我們會密切關注開發人員和使用者的需求并識别哪些特性會給每個人帶來好處

  如上翻譯過來,更多細節請檢視原文.

  目前WP7已經是Beta版本了. Windows Phone 7 支援通路資料幾種方式為: XML、Isolated Storage[SL獨立存儲]、Cloud[雲存儲].    官方意思很明确 暫不支援本地資料庫通路. 難道我們真的沒有其他選擇嗎?未必如此.

  <1>Effiproz For Windows Phone 7

  在上一篇中由Effiproz DataBase來看.NET開源資料庫發展我提到Effiproz開源資料庫.NET多方面支援,其中就包含WP7.這為我們把Effiproz本地資料庫提供通路WP7資料提供了可能.首先說明Effiproz運用在WP7條件:  Windows Phone Developer Tools Beta[最新版本]/VS2010[工具].

  首先建立一個WP7程式 引入Effiproz資料庫DLL[詳見源碼下載下傳]到項目中:

多樣化實作Windows Phone 7本地資料庫通路&lt;上&gt;

  建立一個界面使用者輸入使用者名和密碼并 儲存到Effiproz資料庫中:

多樣化實作Windows Phone 7本地資料庫通路&lt;上&gt;
多樣化實作Windows Phone 7本地資料庫通路&lt;上&gt;

  插入成功後自動查詢并實作出來:

多樣化實作Windows Phone 7本地資料庫通路&lt;上&gt;

  也許有人會注意到兩個FileDB和MemoryDB 按鈕. 其實對應背景中Effproze資料兩種存儲資料模式:檔案和記憶體模式. 上篇中我就曾講到第一個純.NET版本開源資料庫出現問題沖突就是這兩種模式. 記憶體模式中資料提取直接 速度較快. 免去File模式讀取硬碟IO和每次建立Connection的時間. 但是缺點也很緻命. 速度雖然有了一定提升 但最終代價是我們資料無法再記憶體消失後存儲. 也就是資料最終無法持久化存儲檔案中.  EffProze就是從HSQL繼承而來. 是以儲存這兩種模式 供使用者更多場景下選擇. 先看一下FileDB模式代碼實際建立:

private
    
   void
    btnFile_Click(
   object
    sender, RoutedEventArgs e)
      {
          
   //
   isolated storage database
   
          
   string
    connectionString 
   =
    
   "
   connection type=FILE; initial catalog=TestDb; user=SA; password=
   "
   ;
          
   using
    (EfzConnection conn 
   =
    
   new
    EfzConnection(connectionString))
          {
              conn.Open();
              
   string
    sql 
   =
    
   "
   CREATE TABLE Test(username varchar(100), password varchar(100));
   "
   ;
              EfzCommand cmd 
   =
    conn.CreateCommand();
              cmd.CommandText 
   =
    sql;
              cmd.ExecuteNonQuery();
              
   //
   擷取輸入資料
   

                 
   string
    getusername 
   =
    
   this
   .nametxt.Text;
              
   string
    getpass 
   =
    
   this
   .passtxt.Text;
              sql 
   =
    
   "
   INSERT INTO Test(username , password ) VALUES('
   "
    
   +
    getusername 
   +
    
   "
   ','
   "
   +
   getpass
   +
   "
   ');
   "
   ;
              cmd.CommandText 
   =
    sql;
              
   int
    count
   =
   cmd.ExecuteNonQuery();
              
   if
    (count 
   ==
    
   1
   )
              {
                  MessageBox.Show(
   "
   資料插入成功!
   "
   );
              }
              
   else
   
              {
                  MessageBox.Show(
   "
   資料插入失敗!
   "
   );
              }
              
   //
   執行查詢操作
   

                 sql 
   =
    
   "
   SELECT * FROM TEST;
   "
   ;
              cmd.CommandText 
   =
    sql;
              EfzDataReader reader 
   =
    cmd.ExecuteReader();
              reader.Read();
              
   //
   添加結果顯示
              
   //
   MessageBox.Show(string.Format("使用者名={0} —— 登入密碼={1}", reader.GetInt32(0), reader.GetString(1)));
   

                 tbkText.Text 
   =
    String.Format(
   "
   使用者名 = {0}, 登入密碼 = {1}, 模式=檔案模式 
   "
   , reader.GetString(
   0
   ), reader.GetString(
   1
   ));
          }
      }
        

  EffProze資料庫基本上引入T-SQL大部分關鍵字支援,基本上合ADO.NET連接配接資料庫方式雷同. 這也讓.NET程式員不用再看EffProze新的API痛苦,而通過ADO.NET方式對比即可輕松編碼.在代碼中連接配接字元串中connection type=FILE/Memory 每次連接配接都需要指定采用資料庫模式. 這是必須的. Memory模式大同小異不在贅述。

  當有了EffProze資料庫在WP7中作一些複雜資料操作. 是否考慮我們我們這樣在代碼方式太過粗糙原始. 我們需要一個查詢工具。

  當然EffPoze官方也為我們考慮到這點. 特意推出一款QueryTool. 當然有多個版本的,你想快速體驗可以通路QueryTool in Silverlight 4 liveDemo 把QueryTool利用Silverlight 版本 4來實作. 另外一個版本需要到官方下載下傳 QueryTool 1.2 Version[點選下載下傳]:  提示目前工具支援.NET版本是3.5以上 本地運作:

多樣化實作Windows Phone 7本地資料庫通路&lt;上&gt;

  如上提示我們需要打開資料庫檔案,Effproze資料庫檔案格式為: [.properties]  編寫的SQL腳本對應格式為:[.Script]和SQl那一套完全不同.  下載下傳檔案中有執行個體資料庫SamplyDB. 打開:

多樣化實作Windows Phone 7本地資料庫通路&lt;上&gt;

  很簡單布局,類似SQLSErver. 對T-SQl标準中關鍵字全面進行高亮支援. 這比SQlite工具要友好. 但我個人使用總體覺得很難受.  使用者體驗不太好. 其中涉及幾個方面:

  A:對T-Sql标準的有些關鍵字文法檢查太過于嚴密. 大小寫敏感. 寫T-Sql出錯幾率大大增加.

  B:工具功能過于簡單. 左邊菜單中除了展出和隐藏沒有任何對DataBase和表 以及View /Proc的直接操作 隻能用T-sql, 這樣一來 我們隊資料庫操作全部靠T-sql 工作量劇增.

  C:最令我不舒服的是 每次出現錯誤提示太過于簡單. 特别大批量T-SQl 無法準确定位錯誤大概位置 那就更讓人望而生畏了.

  D:沒有批量資料導入導出. 對于資料插入 沒有這樣的功能 工作量 真是太令人後怕了.

  是以這個對使用這個工具原則是: 能避免使用就盡量避免使用. 基本上我昨天調試一個對資料庫所有存儲過程加密 調到最後看到下面始終不變錯誤提示我先崩潰掉了.真是很杯具啊. 各位也可以适當使用.

  如上是EffProze資料庫對WP7資料通路支援一個簡單示例以及基本工具使用. 如有疑問請在留言中提出.我會及時回複 ,提供EffProze use In WP7本篇源碼下載下傳:

   /Files/chenkai/EffProzeInWp7Codechenkai.rar

  <2>SQlite For Windows  Phone 7

  在本地資料庫通路其實我最先嘗試SQlite,作為移動平台Android預設資料庫大量運用,沒有其他原因—隻是因為我個人對Sqlite操作很熟. 雖然沒有了WP7官方的支援. 但是開源社群力量無線的. 國外有人改寫開源Sqlite 3版本使其支援WP7本地資料通路. 我們需要添加一個DLL: Community.CsharpSqlite.WP.dll [源碼中]引用.

多樣化實作Windows Phone 7本地資料庫通路&lt;上&gt;
多樣化實作Windows Phone 7本地資料庫通路&lt;上&gt;
多樣化實作Windows Phone 7本地資料庫通路&lt;上&gt;

  建立一個簡單頁面測試 添加資料後自動查詢資料并顯示ListBox中,插入資料成功 把插入資料通過自動查詢方式顯示在ListBox中 添加資料代碼:

private
    
   void
    AddUserInfor_Click(
   object
    sender, RoutedEventArgs e)
      {
          
   //
   使用者資訊
   

             WP7_LocalDBDemo.DataEntity.Customer newcustomer 
   =
    
   new
    DataEntity.Customer 
          {
              Username
   =
   this
   .username.Text,
              Password
   =
   this
   .passsword.Text
          };
          
   string
    dbname 
   =
    
   @"
   wp7db.db3
   "
   ;
          
   string
    getreply 
   =
    
   string
   .Empty;
   //
   回調資訊

         
   //
   如果資料庫檔案不存在 自動建立
   

             Sqlite3.sqlite3 newsqlite 
   =
    
   new
    Sqlite3.sqlite3();
          
   int
    getres 
   =
    Sqlite3.sqlite3_open(dbname,
   ref
    newsqlite);
          
   if
    (getres 
   ==
    Sqlite3.SQLITE_OK)
          {
              
   //
   建立表
   

                 
   string
    sql 
   =
    
   @"
   Create Table Customer
                               (
                                  customername varchar(100),
                                  customerpass varchar(100)
                               )  
   "
   ;
              Sqlite3.exec(newsqlite, sql, 
   0
   , 
   0
   , 
   0
   );

              
   string
    insertsql 
   =
    
   @"
   insert into Customer Values('
   "
   +
   newcustomer.Username
   +
   "
   ','
   "
   +
   newcustomer.Password
   +
   "
   ')
   "
   ;
              
   int
    getinsertres 
   =
    Sqlite3.exec(newsqlite, insertsql, 
   0
   , 
   0
   , 
   0
   );

              
   if
    (getinsertres 
   ==
    Sqlite3.SQLITE_OK)
              {
                  MessageBox.Show(
   "
   資料插入成功!
   "
   );
              }
              
   else
   
              {
                  MessageBox.Show(
   "
   資料插入失敗!
   "
   );
              }

              
   //
   自動查詢資料 
   

                 
   string
    querysql 
   =
    
   @"
   select * from Customer
   "
   ;
              Sqlite3.dxCallback getcallback 
   =
    
   new
    Sqlite3.dxCallback(TakeCallmethod);

              
   int
    getlocalres
   =
   Sqlite3.sqlite3_exec(newsqlite,querysql,getcallback,
   null
   ,
   ref
    getreply);
              
   if
    (getlocalres 
   ==
    Sqlite3.SQLITE_OPEN_READWRITE)
              {
                  
   //
   需要一個執行Reader API?
                  
   //
   this.listBox1.Items.Add(getresdd.ToString());
   

                 }
          }
      }
        

  SQlite 3修改後能夠支援對WP7資料通路 .大概方式基本同EffProze有些雷同.  但是在實際編碼中.Effproze封裝API的基本同ADO.NET相似. 這樣廣大的.NET程式員無需再熟悉EffProze資料庫自己API, 而修改SQlite 3支援WP7 不同的是. 這裡SQlite 3完全創造自己的一套API. 和原來支援.NET 通路的ADO.NET For SQlite 3  DataProvders完全不同. 沒有任何關聯.

  那就痛苦了.是以我們需要一個SQlite 3通路WP7 的詳細API.  但是很遺憾.如果通路到這份API 需要翻牆.具體位址:Sqlite 3 For Windows Phoen Created API通路位址:  Sqlite 3 For Wp7 API 如有哪位同志翻牆成功 請備份這份API貢獻出來吧.

  SQlite 3支援了WP7的本地資料通路. 但是SQlite 3與EffProze最大特點是Sqlite 3沒有資料庫連結模式之分[記憶體/檔案模式], 我在做完這個執行個體後 測試發現. 硬碟上不存在wp7db.db3這個檔案. 是以我懷疑修改後SQlite 3版本對資料存儲模式應該放到記憶體中的. 當然這是我個人猜測. 沒有得到作者本人的證明.

  如上寫了一個建的Sqlite For Wp7 DEmo. 源碼下載下傳如下:

  /Files/chenkai/WP7_LocalDBDemo.rar

  <3>結語

  本篇主要驗證EffProze和修改Sqlite 資料庫對Windows Phone 7 本地資料通路支援.  測試結果是可行的.這是第一篇 下一篇我會詳細介紹其他方式來做WP7本地資料通路.  當然如上也是我個人測試. 難免會有纰漏的地方. 如果喲疑問請及時留言. 我會及時回複.

  參考資料:

  Sqlite 3 For Windows Phoen Created

  Sqlite 3 For Wp7 API

  LocalDAtaBase  For Windows  Phone 7

  DotaSys Windows  Phone 7  Demo