一、 概述
PPC程序與桌面PC進(jìn)行通信的編程方式目前有兩種,1、利用Socket編程與桌面程序進(jìn)行通信;2、利用RDA和Replication(復(fù)制)進(jìn)行數(shù)據(jù)庫編程來完成與桌面SQL Server數(shù)據(jù)庫的存取。利用Socket編程實(shí)際上就是通過TCP/IP協(xié)議與桌面PC進(jìn)行通信,它可以很方便的傳輸一般類型的數(shù)據(jù),譬如:字符串、整數(shù)以及字節(jié)等,但是如果需要傳輸類型化的數(shù)據(jù)則需要程序員自己去封裝,而且若想由智能設(shè)備從桌面數(shù)據(jù)庫引擎中返回指定數(shù)據(jù)庫表的數(shù)據(jù),必須編寫桌面接口服務(wù)程序來查詢數(shù)據(jù)并將結(jié)果通過Socket返回給智能設(shè)備。那么如何才能在Pocket PC上做到像在桌面PC上一樣存取本地?cái)?shù)據(jù)庫甚至是遠(yuǎn)程桌面PC的數(shù)據(jù)庫呢?通過在智能設(shè)備Pocket PC上運(yùn)行的SQL Server CE 我們便可以輕松存取放置在Pocket PC上的SQL Server CE數(shù)據(jù)庫,還可以通過SQL Server CE中的RDA或者合并復(fù)制快速實(shí)現(xiàn)從智能設(shè)備上存取遠(yuǎn)程桌面SQL Server2000的數(shù)據(jù)庫。
二、技術(shù)要點(diǎn)
SQL Server CE 全名是Microsoft SQL Server 2000 Windows CE Edition,它為移動(dòng)智能設(shè)備和嵌入式設(shè)備提供了一種存取輕量級(jí)數(shù)據(jù)庫的解決方案。通過使用Microsoft Visual Studio .NET 或者 Microsoft eMbedded Visual Tools等開發(fā)工具,我們可以將SQL Server的企業(yè)數(shù)據(jù)管理能力擴(kuò)展到基于Windows CE的智能平臺(tái)之上。SQL Server CE可以應(yīng)用到三種典型的環(huán)境中:
1、開發(fā)環(huán)境,即用于開發(fā)基于SQL Server CE程序的桌面PC,該桌面PC必須包括Microsoft Visual Studio .NET或者M(jìn)icrosoft eMbedded Visual Tools 3.0和Pocket PC SDK開發(fā)工具;
2、客戶端環(huán)境,是用于運(yùn)行基于SQL Server CE程序的Pocket PC設(shè)備,當(dāng)設(shè)備沒有可用的網(wǎng)絡(luò)連接時(shí),可以使用Microsoft ActiveSync來與服務(wù)器環(huán)境桌面PC進(jìn)行線纜連接;
3、服務(wù)器環(huán)境,是運(yùn)行Microsoft Internet Information 服務(wù)(IIS) 和Microsoft SQL Server實(shí)例的計(jì)算機(jī),可以將IIS和SQL Server部署在同一臺(tái)已算機(jī)上,也可以分別配置到多臺(tái)計(jì)算上。RDA和合并復(fù)制都需要通過IIS來與SQL Server進(jìn)行通信。
SQL Server CE 依靠幾個(gè)組件來與SQL Server進(jìn)行數(shù)據(jù)交換:
1、數(shù)據(jù)庫引擎用于管理基于Windows CE設(shè)備上的數(shù)據(jù)存儲(chǔ),并且跟蹤數(shù)據(jù)庫記錄的添加、更新和刪除操作;
2、SQL Server CE Client Agent 是運(yùn)行在Windows CE設(shè)備上的用于連接的組件,包括復(fù)制對(duì)象、RDA對(duì)象和數(shù)據(jù)庫引擎,使用這些對(duì)象應(yīng)用程序可以控制與SQL Server的連接;
3、SQL Server CE Server Agent 處理來自SQL Server CE Client Agent的Http請(qǐng)求。當(dāng)SQL Server CE Client Agent通過Http協(xié)議向SQL Server CE Server Agent發(fā)送請(qǐng)求時(shí),SQL Server CE Server Agent會(huì)與SQL Server進(jìn)行連接并將查詢的記錄集通過Http協(xié)議再傳回給SQL Server CE Client Agent,所有數(shù)據(jù)的傳送都要依賴IIS來完成。
由上述通信過程我們知道,SQL Server CE 的遠(yuǎn)程連接和存取需要使用Web傳輸協(xié)議Http 或者Https,SQL Server CE Client Agent必須運(yùn)行在Windows CE設(shè)備上,SQL Server CE Server Agent則運(yùn)行在桌面PC上,而且該計(jì)算機(jī)還必須安裝有IIS以便使用RDA 或合并復(fù)制來和SQL Server通信。SQL Server CE 支持的網(wǎng)絡(luò)連接有以太網(wǎng)、無線局域網(wǎng)和無線廣域網(wǎng)。通過使用Microsoft ActiveSync,Pocket PC設(shè)備可以使用串口、紅外線或者USB直接與桌面PC上的SQL Server連接,也可以進(jìn)行SQL Server CE與桌面SQL Server 的連接測(cè)試。
Remote Data Access (RDA)對(duì)象是Microsoft SQL Server 2000 Windows CE (SQL Server CE)用于可編程存取遠(yuǎn)程Microsoft SQL Server 2000 或者M(jìn)icrosoft SQL Server version 7.0 數(shù)據(jù)庫的ActiveX控件,我們可以使用RDA存取遠(yuǎn)程數(shù)據(jù)庫就像是在桌面PC上操作本地?cái)?shù)據(jù)庫一樣簡(jiǎn)單。
三、設(shè)計(jì)思路
我們將使用Visual Basic .Net創(chuàng)建“任務(wù)管理程序 For PPC”項(xiàng)目來展示如何利用RDA來完成PPC與PC間的數(shù)據(jù)庫連接和存取。一名客戶經(jīng)理助理或銷售人員必須知道今天都要完成哪些任務(wù),上級(jí)領(lǐng)導(dǎo)對(duì)自己都有哪些安排等等信息,雖然可以使用Email或者IM程序進(jìn)行接收和查看,但是如果我們只拿Pocket PC設(shè)備能否完成任務(wù)的接收呢?答案當(dāng)然是肯定的。
在Pocket PC上我們創(chuàng)建數(shù)據(jù)庫客戶端程序,編寫RDA程序需要用到.net壓縮框架中System.Data.SqlServerCe命名空間中的SqlCeRemoteDataAccess類。從桌面PC查詢并獲取記錄集到Pocket PC上我們需要使用rda.pull方法,pull有多種重載版本,我們使用最常用的版本,localTableName 是將要接收提取的 SQL Server 記錄的 SQL Server CE 本地表的名稱。sqlSelectString 為任何有效的 Transact-SQL 語句,包括 SELECT 語句和存儲(chǔ)過程,它們指定從遠(yuǎn)程 SQL Server 數(shù)據(jù)庫中提取哪些表、列和記錄以存儲(chǔ)在 SQL Server CE 數(shù)據(jù)庫中。 oledbConnectionString 是連接 SQL Server 數(shù)據(jù)庫時(shí)使用的 OLE DB 連接字符串。 trackOption 表示 SQL Server CE 是否跟蹤對(duì)提取表所做的更改,以及提取的表上存在的索引是否轉(zhuǎn)到具有主鍵約束的設(shè)備。我們使用的版本為:
…. rda.Pull("itemlist", "Select * from itemlist where emp_id='" + EMPId + "'", RemoteConnString, RdaTrackOption.TrackingOnWithIndexes) …. |
TrackingOnWithIndexes指示 SQL Server CE跟蹤對(duì)所提取表的所有更改。在本地表上同時(shí)創(chuàng)建 SQL Server 表上存在的索引和主鍵約束。
編寫PPC數(shù)據(jù)庫程序所用到的控件和類與編寫桌面數(shù)據(jù)庫程序具有相似性,SqlCeConnection對(duì)應(yīng)SqlConnection,SqlCeDataAdapter對(duì)應(yīng)SqlDataAdapter,SqlCeCommand對(duì)應(yīng)SqlCommand等,SqlCeConnection 對(duì)象表示到智能設(shè)備上的數(shù)據(jù)源的一個(gè)連接,需要向ConnectionString傳遞有效的連接字符串,譬如:
LocalConnString = "Data Source=\Program File\Task\RDA.sdf" |
Sdf文件是SQL Server CE 數(shù)據(jù)庫文件。 SQL Server CE 只支持一次一個(gè)連接,但是多個(gè)命令可以共享同一連接。在SqlCeConnection連接打開的情況下,可以創(chuàng)建SqlCeCommand對(duì)象,并設(shè)置用于執(zhí)行或返回記錄集的SQL語句的Commandtext屬性,SqlCeCommand 調(diào)用的 SQL 語句不支持傳遞參數(shù)的命名參數(shù),必須使用問號(hào) (?) 占位符,也可以自定義組成SQL語句的字符串,例如:
…… Dim conn As New SqlCeConnection conn.ConnectionString = LocalConnString Dim selectCMD As SqlCeCommand = New SqlCeCommand selectCMD.CommandText = "update itemlist set finished=1 where id=" + id conn.Open() selectCMD.ExecuteNonQuery() …… |
應(yīng)用程序可以使用rda.push方法將 SQL Server CE 跟蹤提取表中的更改傳送回原始 SQL Server 表。localTableName 是指已經(jīng)從 SQL Server 提取的記錄的 SQL Server CE 本地表的名稱。oledbConnectionString 為連接 SQL Server 數(shù)據(jù)庫時(shí)使用的 OLE DB 連接字符串。batchOption 表示正發(fā)送回 SQL Server 表的更改是組成一批共用同一事務(wù),還是分別應(yīng)用。我們的版本需要將所有行組成一批,歸并到一個(gè)事務(wù)推入SQL Server。
rda.Push("itemlist", RemoteConnString, RdaBatchOption.BatchingOn) |
四、 環(huán)境配置及程序?qū)崿F(xiàn)
很多網(wǎng)友不能成功運(yùn)行SQL Server CE 的RDA和合并復(fù)制程序很大程度都是因?yàn)榕渲脝栴}。正確安裝SQL CE和配置IIS及SQL Server 2000是運(yùn)行SQL CE數(shù)據(jù)庫程序的關(guān)鍵。安裝SQL Server CE時(shí)需要注意,安裝程序在安裝服務(wù)器工具時(shí)會(huì)抱錯(cuò),這是SQL Server CE本身與SQL Server 2000存在兼容性及安全性問題,解決的辦法是先忽略,然后更新桌面SQL Server 2000數(shù)據(jù)庫引擎到SP3或SP4,根據(jù)所做的更新版本還需要運(yùn)行相應(yīng)的更新程序SQL Server CE 2.0 SP3 For SQL Server 2000 SP3或者SQL Server CE 2.0 SP4 For SQL Server 2000 SP4,這樣SQL Server CE的服務(wù)器組件就可以順利地安裝到了計(jì)算機(jī)中,然后運(yùn)行其附帶的Configure Connectivity Support in IIS創(chuàng)建IIS虛擬目錄sqlce,其指向的實(shí)際本地路徑為:C:\Program Files\Microsoft SQL Server CE 2.0\Server\,可以更改該文件夾路徑為其它,但該文件夾下必須放置著SQL Server CE Server Agent的相關(guān)文件,比如:sscesa20.dll。下一步需要配置存取該虛擬目錄的用戶、權(quán)限及身份驗(yàn)證方式,我們可以選擇匿名訪問,并接受IIS的默認(rèn)來賓用戶,一般以IUSR開頭,在存取權(quán)限中需要選中讀取和目錄瀏覽兩項(xiàng),見下圖。
![]() 選中讀取和目錄瀏覽兩項(xiàng) |
配置就緒后,我們可以檢測(cè)SQL Server CE Server Agent工作是否正常,啟動(dòng)IE,在地址欄中輸入 Http://localhost/sqlce/sscesa20.dll,或者將localhost改為實(shí)際的主機(jī)名稱,瀏覽器返回“SQL Server CE Server Agent”說明SQL Server CE Server Agent運(yùn)行正常,IIS配置正確。
![]() 身份驗(yàn)證方法
![]() 權(quán)限設(shè)置
![]() 測(cè)試結(jié)果正常 |
接下來需要配置SQL Server 2000,我們需要在桌面SQL Server 2000中創(chuàng)建名為Task數(shù)據(jù)庫,包含Employee員工表和ItemList任務(wù)表,為ItemList表中ID字段創(chuàng)建主鍵和索引,并且添加在IIS中設(shè)置的可以訪問sqlce虛擬目錄和其下文件的IIS來賓用戶,這樣該用戶就可通過IIS來存取SQL Server 2000的數(shù)據(jù)庫了。
![]() 數(shù)據(jù)庫
![]() 員工表
![]() ItemList任務(wù)表
![]() 虛擬目錄和來賓用戶 |
Pocket PC和桌面PC網(wǎng)絡(luò)連接可以使用Microsoft ActiveSync,也可以使用無線WiFi 802.1x。由于我們是與單臺(tái)桌面PC連接,需要在其上同時(shí)安裝IIS和SQL Server 2000。實(shí)際使用得知SQL Server CE 2.0運(yùn)行在桌面服務(wù)環(huán)境的服務(wù)器工具與SQL Server 2000在連接上存在一定問題,微軟對(duì)此問題的解決辦法是:首先將SQL Server 2000打上SP3或者SP4,同時(shí)根據(jù)SQL Server 2000的補(bǔ)丁版本,還需要給SQL Server CE 2.0打上用于SQL Server 2000 SP3或者 SQL Server 2000 SP4的補(bǔ)丁,SQL Server CE的服務(wù)器組件才能順利工作,上述更新和補(bǔ)丁程序在微軟網(wǎng)站上都有下載。
配置結(jié)束后啟動(dòng)Visual Studio .Net 2003,單擊文件 – 新建 – 項(xiàng)目 - Visual Basic 項(xiàng)目 - 智能設(shè)備應(yīng)用程序,創(chuàng)建空項(xiàng)目。整個(gè)程序由一個(gè)Form窗體MainForm組成,其上包含兩個(gè)Panel組件和一個(gè)Button組件,我們把程序分為兩個(gè)主界面,一個(gè)為登錄界面,一個(gè)為操作界面,分別對(duì)應(yīng)兩個(gè)Panel控件,當(dāng)?shù)卿浻肞anel顯示時(shí),操作用Panel則隱藏,當(dāng)?shù)卿洺晒髢蓚(gè)Panel的顯示屬性則相反。Button控件提供退出操作。登錄用Panel上面包含幾個(gè)TextBox和Button控件供填寫SQL Server CE Server Agent 的Web地址、要連接的遠(yuǎn)程SQL Server 2000服務(wù)器名稱、能夠存取桌面SQL Server數(shù)據(jù)庫的用戶名和密碼,以及要登錄的員工ID和密碼等必要的登錄信息。運(yùn)行在實(shí)際設(shè)備上的圖示如下:
運(yùn)行在實(shí)際設(shè)備上的圖示 |
當(dāng)單擊”登錄”按鈕時(shí),程序首先在智能設(shè)備上創(chuàng)建SQL Server CE本地?cái)?shù)據(jù)庫sdf文件,本程序下載的所有表都保存在該數(shù)據(jù)庫中:
…… ' 根據(jù)指定的sdf文件路徑創(chuàng)建本地的用戶數(shù)據(jù)庫文件用于RDA的PULL en = New SqlCeEngine("Data Source=" & LocalDatabaseFile) en.CreateDatabase() …… |
然后創(chuàng)建RDA對(duì)象的實(shí)例,并填寫用于和遠(yuǎn)程SQL Server CE Server Agent 通信的相關(guān)信息。下載允許登錄PPC的合法的用戶信息數(shù)據(jù)到本地表:
rda.Pull("UserInfo", "Select * from employee where emp_id='" + EMPId + "' and emp_password='" + Password + "'", RemoteConnString, RdaTrackOption.TrackingOff) |
UserInfo表返回的是就是登錄用戶的記錄信息,請(qǐng)注意RdaTrackOption的值為TrackingOff,因?yàn)槲覀儧]有在PPC上設(shè)置更改用戶信息的操作,所以沒必要跟蹤該表。如果用戶名和密碼驗(yàn)證通過,UserInfo表的記錄數(shù)就為1,也就是大于0,否則沒有記錄,然后我們通過使用SqlCeConnection、SqlCeDataAdapter、SqlCeDataReader以及DataTable返回UserInfo表的所有記錄,一旦記錄數(shù)為0則不允許登錄:
If dtLocalUserInfo.Rows.Count > 0 Then '驗(yàn)證通過 CurrentLogonUserID = dtLocalUserInfo.Rows(0).Item("emp_id").ToString CurrentLogonUserName = dtLocalUserInfo.Rows(0).Item("emp_name").ToString Return True Else '驗(yàn)證失敗,返回false Return False End If |
登錄成功后根據(jù)登錄用戶名只返回其相關(guān)的任務(wù)記錄,并將任務(wù)記錄保存在名為” itemlist”的表中:
rda.Pull("itemlist", "Select * from itemlist where emp_id='" + EMPId + "'", RemoteConnString, RdaTrackOption.TrackingOnWithIndexes) |
由于RDA不會(huì)保持記錄鎖,push操作會(huì)無條件的將所有數(shù)據(jù)改動(dòng)都應(yīng)用到SQL Server中,所以容易引起當(dāng)前數(shù)據(jù)庫的其他用戶的更新數(shù)據(jù)的丟失。我們需要按照一定的篩選條件過濾我們感興趣的記錄,以便獲取唯一且不同于其它用戶返回的記錄集。TrackingOnWithIndexes說明在PPC上對(duì)任務(wù)狀態(tài)的更改將會(huì)被跟蹤,在后面的同步操作時(shí)會(huì)根據(jù)跟蹤的變化將更改更新到遠(yuǎn)程數(shù)據(jù)庫中。
任務(wù)記錄成功獲得后,我們隱藏登錄用Panel而將操作用Panel置于頂層用于對(duì)任務(wù)記錄的添加、狀態(tài)更新、刪除已經(jīng)同步操作等。
用listview控件來顯示任務(wù)記錄,我們遍歷返回的itemlist表,每一條記錄創(chuàng)建一個(gè)ListViewItem,并添加到listview中以便顯示:
While Reader.Read Dim ls As New ListViewItem(Reader.Item("ID").ToString) ls.SubItems.Add(Trim(Reader.Item("TaskName").ToString)) ls.SubItems.Add(Trim(Reader.Item("TaskContent").ToString)) ls.SubItems.Add(Reader.Item("Finished").ToString) lvItemList.Items.Add(ls) End While |
向SQL Server CE表添加、刪除和更新操作同桌面數(shù)據(jù)庫操作相似,例如添加操作:
selectCMD.CommandText = "insert into itemlist (ID,TaskName,TaskContent,Finished,EMP_ID) values (" + _ TextBox1.Text + "," + _ "'" + taskname + "'" + "," + _ "'" + taskcontent + "'" + "," + "0" + "," + "'" + CurrentLogonUserID + "'" + ")" selectCMD.CommandTimeout = 30 conn.Open() selectCMD.ExecuteNonQuery() |
對(duì)智能設(shè)備本地表進(jìn)行更新后還需要將改動(dòng)保存到遠(yuǎn)程SQL Server中去,我們使用如下代碼:
rda.Push("itemlist", RemoteConnString, RdaBatchOption.BatchingOn) |
將更改成批推入遠(yuǎn)程SQL Server中,注意:只有跟蹤的提取表才可以執(zhí)行Push操作。運(yùn)行在實(shí)際設(shè)備上的圖示如下:
![]() 運(yùn)行在實(shí)際設(shè)備上的圖示 |
該程序成功運(yùn)行在Windows XP SP2和Dell X3i(Pocket PC 2003)環(huán)境下。