天天看點

VS2008下開發Sql CE2.0應用程式

Microsoft SQL 2000 Windows CE Edition(又稱為SQL Server CE)是用于移動裝置上的小型關系資料庫。SQL Server CE的發展曆程從1.0開始,當時.NET的技術架構還不能應用到移動裝置上,這個時候大家在開發基于資料庫的移動應用時,采用的是Embedded Visual Tools 3.0中的VB或VC++,使用OLE DB for SQL Server CE或ADOCE通路SQL Server CE資料庫。随着.NET Compact Framework的推出,SQL Server CE也推出了2.0,2.0加入了更多的新功能,并在很多性能參數都有較大的提高,但更重要的是從此可以在Visual Studio .NET中通過ADO.NET通路SQL Server CE的資料庫了。

    SQL Server CE 2.0提供了兩種基本方法來連接配接後端SQL Server資料庫:RDA和合并複制。RDA通路功能支援與SQL Server 7.0(和更高版本)資料庫的連接配接,合并複制要求後端必須是SQL Server 2000。

    SQL Server CE與SQL Server之間可以通過RDA和Replication(合并複制)兩種方式進行資料同步。RDA适用于簡單的、不需要全功能的合并複制功能(例如資料沖突處理)的資料同步,而Replication則基于Windows Server 2000的合并複制功能,可以完成更多更複雜的功能。

  RDA全稱是Remote data access,其主要由三部分組成:SQL Server CE資料庫引擎、SQL Server CE用戶端代理和SQL Server CE伺服器端代理。SQL Server CE資料庫引擎負責寫入和讀取SQL Server CE資料庫中的資料;SQL Server CE用戶端代理是RDA在移動裝置上的主要元件,它實作了RDA的主要功能,我們可以通過程式調用它提供的接口以控制RDA;SQL Server CE伺服器端代理位于伺服器端,它與SQL Server CE用戶端代理通過HTTP協定進行通信,接收并處理SQL Server CE用戶端代理的指令。

  RDA支援三個主要的方法,他們分别是:

    Pull

    将SQL Server 2000資料庫中的表“拉”到SQL Server CE中。在調用此方法時,可以設定資料跟蹤選項,如果設定資料跟蹤,則SQL Server CE資料庫引擎會自動跟蹤對資料的插入、修改和删除操作。

    Push

    如果在Pull時設定了資料跟蹤選項,可以将SQL Server CE中的資料“推”回到SQL Server 2000中。在SQL Server CE中對資料的任何修改都會反映到SQL Server 2000中。

    SubmitSQL

    直接向SQL Server 2000資料庫送出一個指令。

    如下圖所示:

VS2008下開發Sql CE2.0應用程式

    合并複制是RDA的一種替代方案,隻能與SQL Server 2000配合使用。合并複制的工作組成與RDA基本類似,但是在伺服器端多了一個SQL Server CE複制提供程式,也就是說SQL Server CE伺服器端代理通過調用SQL Server CE複制提供程式,從SQL Server資料庫中選取一個“快照”傳回給SQL Server CE用戶端代理,用戶端代理在裝置上建立SQL Server CE的資料庫(訂閱資料庫)。對訂閱資料庫的任何修改都會被SQL Server CE資料庫引擎記錄下來,在調用同步方法時,可以把這些修改作用到背景SQL Server資料庫中。

    準備開發環境

  移動服務系統采用Visual Studio .NET開發,如果要開發基于SQL Server CE的應用,隻需要在項目中添加System.Data.SqlServerCe的引用,在運作和部署時系統會自動安裝兩個SQL Server CE的安裝封包件,他們是sqlce.dev.wce4.armv4.CAB和sqlce.wce4.armv4.CAB(armv4這一項會根據不同的平台而有所不同)。sqlce.dev.wce4.armv4.CAB包括Isqlw20.exe和兩個錯誤字元串檔案Ssceerror20en.dll和Msdaeren.dll,他們将被安裝到移動裝置的\Program Files\SQLCE 2.0目錄;sqlce.wce4.armv4.CAB包括将被安裝到\Program Files\SQLCE 2.0目錄下的Ssce20.dll、Ssceca20.dll和安裝到\windows目錄下的Sscemw20.dll。

  isqlw20.exe是SQL Server CE的查詢分析器程式,是SQL Server CE在移動裝置上的主要管理工具。

VS2008下開發Sql CE2.0應用程式

    通過查詢分析器,我們可以建立新的SQL Server CE資料庫,打開和關閉資料庫,在資料庫中建立、删除和維護資料表,維護索引資訊,可以輸入SQL語句并檢視執行結果。

    準備SQL Server CE資料庫

  在開發中使用的SQL Server CE資料庫,可以通過三種方式建立:

    通過isqlw20.exe查詢分析器程式建立;

    通過編寫程式建立資料庫,建立表,插入必要的資料;

    通過RDA或合并複制建立。

  其中,通過RDA方式建立是最容易的方法,因為我們可以先行在SQL Server 2000中建立資料庫,設計表結構,插入必要的資料,然後通過RDA一次性的把SQL Server 2000中的表和資料下載下傳到移動裝置上。

    1) 安裝SQL Server CE

  首先安裝SQL Server 2000,安裝完成後,還需要安裝SP3a或者最新的SP4更新檔。如果希望通過RDA或合并複制與SQL Server 2000進行資料同步,那麼還必須下載下傳SQL Server CE的更新檔。SQL Server CE的更新檔應該與SQL Server 2000的更新檔是一緻的,如果SQL Server 2000的更新檔是SP3a,那麼需要下載下傳SQL Server CE的SP3a的更新檔。 SQL Server CE安裝包、SQL Server CE的SP3a更新檔及SQL Server CE的SP4更新檔均可在微軟的網站下載下傳(http://www.microsoft.com/downloads/)。

  下載下傳完成後,首先安裝SQL Server CE的安裝程式,然後再安裝SQL Server CE的更新檔程式。

  2) 配置RDA

  因為RDA使用HTTP協定實作資料通信,是以伺服器端首先需要安裝并配置好IIS服務。在“開始”-->所有程式-->Microsoft SQL Server CE2.0-->Configure Connectivity Support in IIS啟動SQL Server CE連接配接配置程式。

VS2008下開發Sql CE2.0應用程式

    出現“SQL Server CE Connectivity Management”界面,輕按兩下“Create a Virtual Directory”打開配置向導。在視窗中輸入虛拟目錄的别名。

VS2008下開發Sql CE2.0應用程式

    在界面中選擇必要的安全設定,可以按照業務的實際需求情況選擇,如果不需要額外安全設定,可以選擇允許匿名通路。

    設定完成後,打開浏覽器,輸入:http://localhost/sqlce/sscesa20.dll ,  如果以上設定正确,應該可以出現下圖所示的文字:

VS2008下開發Sql CE2.0應用程式
VS2008下開發Sql CE2.0應用程式

    3) 下載下傳資料庫

  使用isqlw20.exe查詢分析器程式建立一個空的資料庫:MobileService.sdf。

  建立空資料庫也可以使用下面的代碼建立:

    ......

    public string LocalDatabase = "\\My Documents\\MobileService.sdf";

    ......

    if (File.Exists(LocalDatabase))

          File.Delete(LocalDatabase);

    try

    {

          SqlCeEngine engine = new SqlCeEngine("Data Source = "+LocalDatabase

                +";password=test;encrypt database=TRUE");

          engine.CreateDatabase();

          engine.Dispose();

          MessageBox.Show("ok");

     }

     catch (Exception ex)

     {

          MessageBox.Show(ex.ToString());

     }

  首先判斷\MobileService.sdf檔案是否已經存在,如果已經存在,則先删除該檔案。在建立資料庫時,用的是SqlCeEngine類的CreateDatabase方法,CreateDatabase會根據LocalConnectionString屬性表示的連接配接字元串建立SQL Server CE資料庫。在連接配接字元串中的password和encrypt database 屬性是可選項,但是如果使用了encrypt database 屬性則必須包含password屬性。SqlCeEngine類還有一個很重要的方法是Compact,Compact方法用于回收SQL Server CE資料庫中浪費的空間,可用于更改SQL Server CE資料庫的排列順序、加密方式或密碼。

    需要注意的是,建立VS2008移動裝置工程(如Mobile 5.0 Pocket PC模拟器)時,可以先不加任何功能代碼,僅添加引用System.data.SqlServerCe,編譯運作,系統會自動向模拟器加載需要的DLL子產品,并放在模拟器

\Program Files\Microsoft SQL Server Compact Edition\v3.5中。可以通過開始-->所有程式-->VS2008-->

Visual Studio Remote Tools-->遠端檔案檢視器檢視,資料庫查詢分析器isqlw35.exe檔案也在該目錄的CN路徑下。

VS2008下開發Sql CE2.0應用程式
VS2008下開發Sql CE2.0應用程式

    在點選×号退出模拟器時,選擇儲存目前狀态,就可以不必每次編譯程式都重新加載DLL檔案了。如果想在虛拟器中删除工程檔案,可以在遠端檔案檢視器中删除,但必須先使用遠端程序檢視器删除工程檔案程序。删除資料庫檔案也是一樣,先要在遠端程序檢視器中删除isqlw35.exe,因為要删除的檔案正在被使用。

    實驗pull方法:

    在上面按鈕點選事件處理方法中添加以下代碼,實作從桌面Northwind資料庫向裝置模拟器本地資料庫MobileService.sdf下載下傳資料表結構及資料記錄:

    string rdaOleDbConnectString = "Provider=sqloledb.1;Data Source=192.168.1.17;

               Initial Catalog=Northwind; User Id=sa;Password=sa";

    SqlCeRemoteDataAccess rda = null;

    rda = new SqlCeRemoteDataAccess();

    //rda.InternetLogin = "MyLogin";

    //rda.InternetPassword = "<password>";

    rda.InternetUrl = "http://192.168.1.17/sqlce/sscesa20.dll";

    rda.LocalConnectionString = @"Data Source=\My Documents\MobileService.sdf;password=test";

    rda.Pull("Region", "Select * from Region", rdaOleDbConnectString);

    在使用SqlCeRemoteDataAccess通路RDA時,需要指定三個重要的參數:

    SQL Server CE伺服器端代理的通路位址,通過SqlCeRemoteDataAccess類的InternetUrl屬性指定;

    連接配接到SQL Server CE資料庫的連接配接字元串,通過SqlCeRemoteDataAccess類的LocalConnectionString 屬性指定;

    SQL Server CE伺服器端代理通路SQL資料庫的連接配接字元串,通過調用Pull、Push或Submit方法時指定。

  另外,如果在伺服器端設定時需要使用者登入,還需要設定InternetLogin屬性和InternetPassword屬性;如果通過代理通路伺服器,還需要指定相關的代理屬性。

  Pull方法中的第一個參數是指定的本地表名稱,如果該名稱的表已經在SQL Server CE資料庫中存在,則該方法會出錯;第四個參數是設定是否打開資料跟蹤選項的,如果設定為不打開跟蹤選項,則第二個參數指定的SQL語句可以從多個表中提取資料,否則隻能從單個表中提取資料。因為我們隻是要下載下傳資料,并不打算采用Push方法上傳資料,是以在此我們可以不指定第四個參數。

    編譯運作程式,在模拟器中提示錯誤“将資料發送到運作IIS的計算機的請求失敗.有關詳細資訊請參閱HRESULT”。網上有一些解決辦法,包括關閉防火牆等,但都無法解決。分析是網絡連接配接問題,試着在模拟器的浏覽器中使用http://192.168.1.17/sqlce/sscesa20.dll連接配接IIS,或者浏覽百度等網頁,未成功,提示未配置網絡連接配接。後根據網上相關文章,執行了以下連接配接配置操作:

    在確定主機已連上網際網路的情況下,按以下步驟設定:

    1、打開ActiveSync ,點選“檔案”——>“連接配接設定”,在“允許連接配接到以下其中一個端口”下選擇“DMA”。

    2、打開 VS2005,點選菜單“工具”——>“裝置仿真管理器”,選擇一個 PocketPC SE 2003模拟器(或其它模拟器,但編譯時應選擇相同模拟器)。在右鍵菜單中點選“連接配接”。等模拟器啟動後,再點選“插入底座”,此時,通過ActiveSync來連接配接到模拟器,并進行資料同步。

    3、在模拟器中,點選“開始”——>“設定”,點選“連接配接”頁籤。

   (1)選擇“網卡”:

    “我的網卡連接配接到”選“預設機關設定”。

     在“點選擴充卡以修改設定:”下面選“AsyncMac NDISWAN Miniport”,選中“使用伺服器配置設定的IP位址”,點選右上角的“ok”,提示“新設定将在下次使用擴充卡時應用。如果擴充卡目前插在裝置中,請先移除,然後重新插入擴充卡以應用設定。”,點選“ok”,“ok”。

    (2)在“連接配接”頁籤中選擇“連接配接”:

     在“進階”頁籤中,點選“選擇網絡”,在“在程式自動連接配接到Internet時,使用:”下面選“機關設定”,預設是“Internet設定”,然後,連續點選右上角的“ok”,“ok”,“X”傳回。

    4、此時,就可以上網了。依次點選“開始”——>“Internet Explorer”,輸入WWW.BAIDU.COM等就會出現頁面了。如還打不開網頁,可在“裝置仿真器管理器”中選中該模拟器,先點選右鍵菜單中的“移除底座”,再點選“插入底座”,重新與ActiveSync連接配接一次(或在ActiveSync連接配接配置中執行連接配接操作),就沒問題了。

    連接配接配置好後,在模拟器的Program中再打開工程,點選按鈕,執行上述資料庫操作,提示“内部錯誤:傳輸消息的HTTP标頭資訊已壞”錯誤,檢查代碼無錯誤,借鑒網上相關文章,分析是SqlServerCe.dll的版本問題,VS2008預設添加的是C:\Program Files\Microsoft SQL Server Compact Edition\v3.5\Devices下3.5版本的System.Data.SqlServerCe.dll檔案。

    為解決這個問題,在其它機器中安裝了VS2005,從目錄D:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v2.0中得到2.0版本的System.Data.SqlServerCe.dll檔案。重新添加引用,再編譯運作,提示:無法找到PInvoke DLL "sscemw20.dll"錯誤,分析是模拟器中sql ce執行環境(如下圖所示)版本不一緻的原因。

    如圖所示,DLL檔案和查詢分析檔案均為3.5版本(對應的DLL檔案可以在C:\Program Files\Microsoft SQL Server Compact Edition\v3.5\Devices\wce500\armv4i或其它裝置類型目錄下找到)。查找sqlce聯機文檔,sqlce2.0所需dll環境包括ssce20.dll、ssceca20.dll、ssceerror20en.dll、isqlw20.exe這幾個Sql Server Ce檔案(可以從CE2.0安裝目錄C:\Program Files\Microsoft SQL Server CE 2.0\Device\Arm\Sa1100中得到,包括dllregister.exe檔案--可以在移動裝置中用于注冊dll檔案);還有安裝ce2.0的server tools時C:\Windows CE Tools\wce300\Pocket PC 2002\dataaccess31\target\arm目錄下的adoce31.dll、adoceoledb31.dll、adoxce31.dll、msdaeren.dll這幾個檔案。

    在遠端檔案檢視器中(使用工具欄中的方向向上的上箭頭)将這些檔案都下載下傳到移動裝置的windows目錄下。

    在遠端檔案檢視器中,從C:\Program Files\Microsoft SQL Server CE 2.0\Device\Arm\Sa1100下将dll檔案注冊器dllregister.exe複制到移動裝置的Windows目錄下。

    在移動裝置(模拟器)中選擇“開始-->資料總管-->windows”,點選運作dllregister,注冊成功。測試證明這些DLL檔案及注冊器都是cpu類型相關的,如這裡的arm。如果注冊不成功,可以選擇其它類型的相關檔案再試一下。

    注冊之後,再試,顯示錯誤:無法找到 PInvoke DLL“sscemw20.dll”。按照前述方法,使用ActiveSync連接配接,錯誤依舊。按照下圖,在遠端檔案檢視器中手工搭建DLL環境,再試,還是不能解決。

VS2008下開發Sql CE2.0應用程式

    以上測試使用Mobile5.0 Pocket PC R2 Square Emulator模拟器,懷疑是因為模拟器中儲存的DLL版本沖突,又使用Mobile5.0 Pocket PC R2 Square Emulator模拟器(相當于使用了一台新裝置)試了一下,仍然顯示該異常。看來主要是因為VS2008與VS2005不同,缺少對SQL CE2.0的支援。不像VS2005,安裝後就有對CE2.0的相容支援,不知在CE2.0已安裝的情況下,重裝VS2008會不會添加對CE2.0的支援。

    稍感欣慰的是在vs2005環境下測試成功。請有興趣的同行也在VS2008下試一下,共同解決這一問題。

    剛接觸嵌入式,感覺開發上與桌面類似,不過環境搭建太啰嗦了,而且相容性不好。不過,現在的軟體開發大多是內建和搭建,真希望這方面的高手多共享一下經驗,共同提高。

    問題解決:

    在前面測試的基礎上,利用VS2005程式(參考VS2005下的Sql CE開發測試)運作時在模拟器Windows目錄下部署的sscemw20.dll檔案。

    首先在VS2005遠端檔案檢視工具中導出sscemw20.dll,再在VS2008遠端檔案檢視工具中導入sscemw20.dll,運作dllregister注冊一下,儲存狀态并退出模拟器,再次編譯并測試程式,運作成功。

    這一次的測試是在另一台機器上,由于先安裝的SQL2005,又安裝的SQL2000,在安裝SQL2000時預設執行個體名選項是不可選的,是以建立的執行個體名為MYSQL(機器名為XH)。按鈕點選事件處理方法代碼如下:

    if (File.Exists(LocalDatabase))

                File.Delete(LocalDatabase);

            try

            {

                SqlCeEngine engine = new SqlCeEngine("Data Source = " + LocalDatabase

                      + ";password=test;encrypt database=TRUE");

                engine.CreateDatabase();

                engine.Dispose();

                //或者Data Source=(local)\\MYSQL

                string rdaOleDbConnectString = "Provider=sqloledb.1;Data Source=XH\\MYSQL;

                      Initial Catalog=Northwind; User Id=sa;Password=sa";

                SqlCeRemoteDataAccess rda = null;

                rda = new SqlCeRemoteDataAccess();

                //rda.InternetLogin = "MyLogin";

                //rda.InternetPassword = "<password>";

                rda.InternetUrl = "http://192.168.2.22/sqlce/sscesa20.dll";

                rda.LocalConnectionString

                         = @"Data Source=\My Documents\MobileService.sdf;password=test";

                rda.Pull("Region", "Select * from Region", rdaOleDbConnectString);

                MessageBox.Show("ok");

            }

            catch (Exception ex)

            {

                MessageBox.Show(ex.ToString());

            }

繼續閱讀