基於SQL Server CE的移動服務系統開發(RDA/Replication)

http://www.51testing.com/html/11/586.html

基於SQL Server CE的移動服務系統開發
 
文章出處:轉載 作者:侯月文 發佈時間:2005-11-04
 
    移動服務是應用比較廣泛的移動解決方案,其核心是利用移動計算和無線通信技術爲企業現場服務人員提供全面、便捷、實時的信息服務。我們現在就爲某電器製造商設計一套用於售後維修服務的移動解決方案。

  該電器製造商目前售後維修服務的基本工作流程是:客戶打電話報修,呼叫中心記錄用戶的基本信息(如姓名、地址和電話等等)和客戶對故障的描述信息,生成維修單,維修服務人員領取維修單,維修服務人員上門爲客戶服務,填寫維修記錄單(如實際故障,維修所用零部件,維修所用時間等),客戶簽字認可,維修服務人員交回維修記錄單,呼叫中心電話回訪客戶。

  採用移動服務系統改造後的工作流程是:客戶打電話報修,呼叫中心記錄用戶的基本信息和客戶對故障的描述信息,生成維修單,維修單通過無線網絡直接發送到維修服務人員的手持設備上,維修服務人員上門爲客戶服務,在移動設備上填寫維修記錄單,客戶在移動設備上簽字認可,維修服務人員把維修記錄單通過無線網絡發回至呼叫中心,呼叫中心電話回訪客戶。

  通過上述新舊流程的對比,可以發現採用移動服務系統之後將顯著的提升維修服務人員的工作效率,大大縮短客戶報修之後的響應時間,對於提升售後服務的質量和客戶滿意度都有極大的益處。

移動服務系統設計

移動數據庫SQL Server CE

  因爲移動服務系統需要下載維修單到移動設備上,並在移動設備上臨時保存維修單,所以在移動設備上需要有一個數據庫系統。我們選擇的移動數據庫系統是SQL Server CE。

  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與我們熟悉的其他關係數據庫相比,有以下的特點:

  1) 打開SQL Server CE數據庫時,是通過指定其數據庫文件所在的完整路徑來打開的。例如,當在EVB中使用ADOCE打開數據庫時,可以用下面的形式:

Dim cn As ADOCE.Connection
Set cn = CreateObject("ADOCE.Connection.3.1")
cn.ConnectionString = "Provider=Microsoft.SQLSERVER.OLEDB.CE.2.0; data source=\Northwind.sdf"
cn.Open

  2) SQL Server CE支持數據庫密碼和數據庫文件加密

  例如,當使用.NET Compact Framework中的SqlCeConnection.Open方法打開數據庫時,可以使用如下的連接字符串:

"data source=\NorthWind.sdf; password="

  當使用ADOCE時,則在連接字符串中必須指定SSCE:Database Password連接屬性。

"Provider=Microsoft.SQLSERVER.OLEDB.CE.2.0; data source=\NorthWind.sdf; SSCE:Database Password="

  3) SQL Server CE同樣支持大量的內部函數,這些函數包括數學函數、字符串函數和內部函數等。

  4) SQL Server CE 2.0 通過 ADO.NET 增加了對參數化查詢的支持。

  例如,我們在構造SQL語句時,可以構造以下的語句,然後再利用ADO.NET的機制替換“?”所代表的參數。對參數化查詢的支持是 SQL Server CE 2.0的新功能。

  "INSERT INTO TableA (col1, col2) VALUES (?, ?)"

  5) 與先前版本的SQL Server CE相比,新版本的另一個改進是加入了更加可靠的錯誤處理功能。SQL Server CE增加了一個名爲SqlCeException的新類,這個類允許您捕捉本機SQL Server CE錯誤並適當地處理它們。

  6) 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數據庫提交一個命令。


    圖1 SQL Server CE與SQL Server數據同步示意圖

      合併複製是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數據庫中。

      移動服務系統在下載維修單時,要滿足兩個基本的條件:一是用戶只能下載分配給自己的維修單;二是隻能下載尚沒有完成的維修單。在上傳維修記錄單時,也要滿足兩個基本條件:一是隻能上傳客戶已經簽名確認的維修記錄單;二是隻能上傳維修服務人員選定的維修記錄單。由此可見,移動服務系統在數據同步時,需要實現一定的義務邏輯規則,如果用RDA或合併複製實現這些業務邏輯規則,會比較麻煩一些,所以我們設計如下的數據同步規則:

    • 數據同步包括兩個部分:移動端和服務器端
    • 服務器端採用IIS+ASP.NET構建應用服務器
    • 移動端與服務器端採用HTTP協議傳輸數據
    • 移動端採用類似http://host/do.aspx?action=GetJobList&user=&date=的URL訪問服務器端
    • 服務器端返回數據時,以SUCCESS表示成功,FAILED表示失敗,記錄之間以“^”爲分隔符,字段之間以“|”爲分隔符
    • 移動端解析服務器端返回數據,如果需要的話更新SQL Server CE數據庫

      開發準備工作

      準備開發環境

        移動服務系統採用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在移動設備上的主要管理工具。


      圖2 SQL Server CE查詢分析器

        通過查詢分析器,我們可以建立新的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服務。在“開始”菜單中運行“Configure Connectivity Support in IIS”啓動SQL Server CE連接配置程序。


      圖3 啓動SQL Server CE連接配置

        出現“SQL Server CE Connectivity Management”界面,雙擊“Create a Virtual Directory”打開配置嚮導。在圖4的窗口中輸入虛擬目錄的別名。


      圖4 SQL Server CE連接管理配置嚮導

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


      圖5 安全設置配置

        設置完成後,打開瀏覽器,輸入:

      http://localhost/sqlce/sscesa20.dll

        如果以上設置正確,應該可以出現圖6所示的文字:


      圖6 設置完畢瀏覽器效果圖

        3) 下載數據庫

        使用isqlw20.exe查詢分析器程序建立一個空的數據庫:MobileService.sdf。

        建立空數據庫也可以使用下面的代碼建立:

      if (File.Exists ("\\MobileService.sdf") )
          File.Delete ("\\MobileService.sdf");
      SqlCeEngine engine = new SqlCeEngine ("Data Source = \\ MobileService;password=test;encrypt database=TRUE");
      engine.CreateDatabase ();
      engine.Dispose();

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

        在Visual Studio .NET中建立一個簡單的移動應用程序,執行下面的代碼就可以通過RDA的Pull方法在移動設備上建立JOB表,並下載SQL Server中JOB表的數據。通過更換不同的表名稱,就可以循環下載SQL Server中所有的表。

      string rdaOleDbConnectString = "Provider=sqloledb; Data Source=10.1.11.18;Initial Catalog=test; User Id=sa;Password=sa";
      SqlCeRemoteDataAccess rda = null;
      rda = new SqlCeRemoteDataAccess();
      rda.InternetLogin = "MyLogin";
      rda.InternetPassword = "";
      rda.InternetUrl = "http://10.1.11.18/sqlce/sscesa20.dll";
      rda.LocalConnectionString = @"Provider=Microsoft.SQLSERVER.OLEDB.CE.2.0;Data Source=\MobileService.sdf";
      rda.Pull(
          "JOB",
          "Select * from JOB",
          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方法上傳數據,所以在此我們可以不指定第四個參數。

  Push方法把SQL Server CE表中的更改傳送回SQL Server表,應用程序必須已經通過調用Pull方法並將RdaTrackOption設置爲TrackingOn或TrackingOnWithIndexes創建了SQL Server CE的數據表。

  SubmitSQL提交在遠程SQL Server的數據庫上執行的SQL語句。它所提交的SQL語句必須是不返回任何數據行的SQL語句。

開發移動服務應用程序

下載維修單數據

  下載維修單需要兩個參數:當前的用戶名和最後一個維修單的時間。先通過查詢數據庫得到最後一個維修單的時間。

SqlCeConnection conn = null;
try
{
    conn = new SqlCeConnection ("Data Source = \\MobileService.sdf;password=test;encrypt database=TRUE");
    conn.Open();
    //查詢當前job中最後一個job的時間
    SqlCeCommand cmd = conn.CreateCommand();
    cmd.CommandText = "select max(jobtime) from job";
    SqlCeDataReader dtr = cmd.ExecuteReader(CommandBehavior.SingleResult);
    string latestdate = "";
    while (dtr.Read())
    {
        if(dtr.IsDBNull(0))
        {
            latestdate = "2005-04-15 0:0:0";
        }
        else
        {
            latestdate = dtr.GetDateTime(0).ToString();
        }
    }
    dtr.Close();
}
catch(SqlCeException ex)
{
    MessageBox.Show(ex.Message);
}
finally
{
    if(conn.State == ConnectionState.Open)
        conn.Close();
}

  使用SqlCeConnection類Open方法打開SQL Server CE數據庫的一個連接。一個SQL Server CE數據庫僅能打開一個唯一的連接,所以在使用時要注意試圖打開多個到數據庫的連接是不會成功的。但是,多個SQL Server CE的命令可以共享同一個打開的連接。使用Open方法打開的連接不會自動關閉,所以必須顯式關閉該連接。

  然後使用SqlCeCommand類的ExecuteReader方法執行了一條SELECT語句,並將執行結果保存到SqlCeDataReader類中,然後用Read方法讀取該記錄。SELECT語句用到了SQL Server CE的內置函數max,可以得到最大的一個日期。

  在使用Read方法讀取記錄時,先使用IsDBNull方法判斷是否爲空,如果job表中原本就沒有記錄的話,使用max函數得到的結果爲空。如果不爲空的話,再調用GetDateTime方法得到結果集中的DateTime格式的值。

//下載維修單
string url ="http://10.1.11.18/MSWEB/Do.aspx?action=GetJobList&user=123&date="+latestdate;
HttpWebRequest req = (HttpWebRequest) WebRequest.Create(url);
HttpWebResponse result = (HttpWebResponse) req.GetResponse();
Stream ReceiveStream = result.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("GB2312");
StreamReader sr = new StreamReader(ReceiveStream,encode);
string resultstring = sr.ReadToEnd();
ReceiveStream.Close();
sr.Close();

  首先用用戶名和最後的維修單時間構造一個URL,然後通過HttpWebRequest類的Create方法打開這個URL,通過HttpWebResponse接收返回的數據,使用Stream讀取返回流中的數據。最後的結果保存在resultstring變量中。

  按照設計的數據同步規則解析保存在resultstring變量中的記錄和字段(代碼略),然後把記錄寫入SQL Server CE數據庫。

//寫入數據庫
cmd.CommandText = "INSERT INTO JOB(id,jobname,jobdesc,jobtime,useraddress,userphone)"
    +"VALUES (<各字段數據>)";
cmd.ExecuteNonQuery();

  使用SqlCeCommand類的ExecuteNonQuery方法執行不需要返回行記錄的SQL語句。

顯示維修單列表

  在.NET Compact Framework中仍然支持數據綁定控件,因此我們在實現維修單列表時,採用DataGrid數據綁定列表控件。在窗口中創建DataGrid控件,命名爲dataGridJobList,然後在屬性窗口中單擊TableStyles項的“…”圖標,將出現TableStyles集合編輯器,如圖7所示:


圖7 TableStyles集合編輯器

  在MappingName中輸入“JOBLIST”,點擊GridColumSytles旁邊的“...”按鈕,設定數據綁定的列映射。在設定列映射時,添加三列,映射名稱分別是id,jobname,jobtime。如圖8所示:


圖8 列映射效果圖

  在Form_load事件中添加數據綁定的代碼:

//數據綁定
this.dataGridJobList.RowHeadersVisible = false;
dataGridJobList.Font = new Font("宋體",9F,FontStyle.Regular );
System.Data.DataSet dsJobList;
System.Data.DataTable dtJobList;
dsJobList = new DataSet();
sql = "select id,jobname,jobtime from job order by jobtime desc";
SqlCeDataAdapter adapter = new SqlCeDataAdapter(sql, conn);
adapter.Fill(dsJobList, "JOBLIST");
dtJobList = dsJobList.Tables["JOBLIST"];
this.dataGridJobList.DataSource = dtJobList;

  通過SqlCeDataAdapter的Fill方法把SQL語句的執行結果填充到DataSet中,取出DataSet中名爲“JOBLIST”的DataTable,把DataGrid控件的數據源屬性DataSource設定爲名稱爲“JOBLIST”的DataTable。通過上述操作就可以完成SQL Server CE數據與一個DataGrid控件的數據綁定。

編輯並保存維修記錄單

  當點擊列表中的維修單時,將彈出維修記錄編輯界面。在DataGrid的MouseUP事件中添加下列代碼將可以獲取當前點擊的是哪一個維修單,並打開維修記錄編輯界面。

DataGrid myGrid = (DataGrid)sender;
DataGrid.HitTestInfo myHitInfo = myGrid.HitTest(e.X,e.Y);
if (myHitInfo.Type == DataGrid.HitTestType.Cell && myHitInfo.Column == 1)
{
    Cursor.Current = Cursors.WaitCursor;
    DataGridCell myCell = dataGridJobList.CurrentCell;
    string jobid = dtJobList.Rows[myCell.RowNumber][0].ToString();
    Cursor.Current = Cursors.Default;
    FrmJob frmJob = new FrmJob(jobid);
    frmJob.ShowDialog();
}

  在FrmJob的Load事件中添加根據jobid查詢維修單詳細信息的代碼,並將查詢結果顯示在界面上。

string sql ="select jobname,jobdesc,jobtime,userphone,useraddress,jobdonedesc from job where id="+jobid;
SqlCeCommand cmdDML = new SqlCeCommand(sql,conn);
cmdDML.CommandType = CommandType.Text;
SqlCeDataReader dtr = cmdDML.ExecuteReader(CommandBehavior.SingleResult);
while (dtr.Read())
{
    this.lblJobName.Text = dtr.GetString(0);
    this.lblJobDesc.Text = dtr.GetString(1);
    this.lblJobTime.Text = dtr.GetDateTime(2).ToString();
    this.lblPhone.Text = dtr.GetString(3);
    this.lblAddress.Text = dtr.GetString(4);
    if(!dtr.IsDBNull(5))
        this.txtDoneDesc.Text = dtr.GetString(5);
}
dtr.Close();

  編輯完成後,使用SqlCeCommand類的ExecuteNonQuery方法執行UPDATE語句更新維修記錄單。

上傳維修記錄單

  上傳維修記錄單時採用的方法與下載基本相同,需要在後臺服務器添加一個新的上傳接口。需要注意的是,因爲HTTP的GET協議的URL長度通常是有限制的,所以如果需要上傳的內容比較多時,需要考慮用POST協議。

結束語

  本文結合移動服務系統的開發過程介紹了SQL Server CE的特點以及安裝、開發SQL Server CE應用程序的方法,如果需要更全面和詳盡的瞭解SQL Server CE,可以參閱SQL Server CE附帶的“Books Onlie”。

  通過本文的介紹,大家可以看到利用ADO.NET開發SQL Server CE的應用程序,在開發方法上與在PC平臺上使用ADO.NET非常類似,但總的說來還是要注意一下幾點:

  1. SQL Server CE是用於移動設備上的一個很輕量級的數據庫系統,其性能受移動設備的存儲能力和計算能力的制約,因此在使用SQL Server CE時,儘量避免大數據量的操作,要儘可能的壓縮SQL Server CE上數據的規模。
  2. SQL Server CE有一些比較特殊的地方需要注意,例如只能打開一個到SQL Server CE的連接,支持數據庫口令和加密,支持部分函數等。
  3. 在使用RDA或合併複製時,要結合自己的數據同步業務邏輯靈活運用,避免生搬硬套帶來更多的不方便。
  4. 注意使用SqlCeEngine類的Compact方法回收 SQL Server CE 數據庫中浪費的空間。如果發現數據庫文件已經達到幾兆甚至將近十兆左右時,可以用Compact方法嘗試壓縮一下數據庫。
發佈了5 篇原創文章 · 獲贊 3 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章