.NET遠程處理框架詳解
第1章 系統(tǒng)總體結構
1.1 總體結構
系統(tǒng)實現需要部署服務器端的遠程對象(即一個DbServerLibrary.dll),服務器端要注冊通道和該遠程對象。客戶端要實現一個本地查詢的服務器,同時根據SQL解析的結果向各個服務器發(fā)送命令,并將結果顯示在客戶端界面,服務器端可以接受并顯示相應的命令。
1.2 關鍵組件結構
系統(tǒng)結構中關鍵的組件有遠程對象,和本地服務器,實現的功能基本一致。下面以遠程對象為例,說明組件的實現。遠程對象在服務器端解決方案下的庫文件中聲明,通過服務器端進行注冊,客戶端通過TCP通道與服務器端遠程對象通信,實現數據集的查詢和傳輸。主要的數據成員有:SqlConnection(SQL Server數據庫的連接對象)、 SqlCommand (SQL命令對象)、SqlDataAdapter(數據適配器,填充數據集)組件——DbServerLibrary。
第2 章 .NET遠程處理框架提供的強大技術
因時間倉促,未實現數據字典,所有實驗要求的SQL經過解析后,直接通過代碼判斷,向相應場地發(fā)送命令。
代碼分為三部分:遠程對象,服務器端代碼和客戶端代碼。
其中:遠程對象部署在各個服務器端,客戶端除了實現查詢命令的解析和傳送外外,還有一個本地服務器,進行相應的本地查詢。
遠程對象代碼:
- usingSystem;
- usingSystem.Runtime.Serialization;
- usingSystem.Data;
- usingSystem.Data.SqlClient;
- usingSystem.Windows.Forms;
- namespaceDbServerLibrary{
- [SerializableAttribute]//ItisveryimportantforRemotingData
- publicclassDbServer:MarshalByRefObject{
- privatestringconnStr;
- privatestringclientSql;
- publicSqlConnectionsqlConn;
- publicSqlCommandsqlComm;
- publicSqlDataAdaptersqlAdapter;
- publicvoidGetClientSql(stringsql){
- if(clientSql!=null){
- clientSql=null;
- }
- clientSql=sql;
- MessageBox.Show(clientSql);
- }
- publicDbServer(){
- //LocalDataInitialize
- cnnStr="DataSource=localhost;InitialCatalog=DDB;UserID=sa;Password=;";
- sqlConn=newSqlConnection(connStr);
- }
- publicDataSetGetDataSet()
- //執(zhí)行select
- DataSetds=newDataSet();
- if(sqlComm!=null){
- sqlComm=null;
- }
- if(sqlConn.State==ConnectionState.Closed){
- sqlConn.Open();
- }
- try{
- sqlComm=newSqlCommand();
- sqlComm.Connection=sqlConn;
- sqlComm.CommandText=clientSql;
- sqlComm.CommandType=CommandType.Text;
- sqlAdapter=newSqlDataAdapter();
- sqlAdapter.SelectCommand=sqlComm;
- sqlAdapter.Fill(ds);
- }
- catch(SqlExceptionex){
- MessageBox.Show(ex.Message);
- }
- returnds;
- }
- publicintExecuteSql()//執(zhí)行insert和delete{
- intaffectedNumber;
- if(sqlComm!=null){
- sqlComm=null;
- }
- if(sqlConn.State==ConnectionState.Closed){
- sqlConn.Open();
- }
- try{
- sqlComm=newSqlCommand();
- sqlComm.Connection=sqlConn;
- sqlComm.CommandType=CommandType.Text;
- sqlComm.CommandText=clientSql;
- affectedNumber=sqlComm.ExecuteNonQuery();
- returnaffectedNumber;
- }
- catch(SqlExceptionex){
- MessageBox.Show(ex.Message);
- return0;
- }
- }
- }
- }
服務器端代碼:
- privatevoidfrmSupplierServer_Load(objectsender,System.EventArgse)
- {TcpChannelchan=newTcpChannel(8888);
- ChannelServices.RegisterChannel(chan);
- //注冊提供服務的遠程對象
- RemotingConfiguration.RegisterWellKnownServiceType(typeof(DbServerLibrary.DbServer)
"DbServer",WellKnownObjectMode.Singleton);- }
客戶端代碼:
解析SQL:SqlParse.cs
- namespaceSupplierClient{
- publicclassSqlParse{
- //得到sql語句的類型
- publicstringGetSqlType(stringsqlText)//typeofSQLstatements{
- }
- //得到select語句要查詢的表名
- publicstringGetSelectTableName(stringsqlText){
- }
- //得到select語句中的where子句
- publicstringGetWhereClause(stringsqlText){
- }
- //得到查詢條件中的字段名
- publicstringGetSelectField(stringsqlText){
- }
- //得到分片依據,返回Scity的值
- publicstringGetSelectCityValue(stringsqlText){
- }
- //設定select語句經解析后的格式
- publicArrayListSetSelectList(stringsqlText){
- }
- //如果沒有分片信息,則向3個場地都發(fā)送命令
- publicArrayListSendToAllSite(stringsqlText){
- }
- //得到insert語句要查詢的表名
- publicstringGetInsertTableName(stringsqlText){
- }
- //根據插入的表和值,設定場地:INSERTINTOSupplierVALUES('no','name','city'),returncity
- publicstringGetInsertCityValue(stringsqlText){
- }
- //如果表名是Supplier,則根據city值設定向哪個場地發(fā)送命令
- publicArrayListSetInsertSite(stringsqlText){
- }
- //生成解析后的insert命令列表
- publicArrayListSetInsertList(stringsqlText){
- }
- namespaceSupplierClient{
- publicclassLocalServer{
- }
- //返回查詢結果
- publicDataSetMakeDataSet(stringsqlText){
- }
- //執(zhí)行插入和刪除操作,并返回影響記錄數
- publicintExecuteSql(stringsqlText){
- }
第4 章 界面
4.1 客戶端
客戶端啟動后,用戶首先在文本框中輸入SQL命令,然后通過解析后向相應場地發(fā)送命令,并將返回的結果集進行合并,顯示在界面中,顯示結果后空白的文本框用來顯示執(zhí)行插入刪除操作時的結果信息。
4.2 服務器
服務器端僅實現對遠程對象的注冊,因此界面不需要實現功能,只需要在啟動時注冊遠程對象即可,接收到的客戶端的用戶命令是通過消息框顯示的。如上圖所示。
第5 章 命令處理及核心算法流程
Insert 操作——
- //得到insert語句要查詢的表名
- publicstringGetInsertTableName(stringsqlText){
- }
- //根據插入的表和值,設定場地:INSERTINTOSupplierVALUES('no','name','city'),returncity
- publicstringGetInsertCityValue(stringsqlText){
- }
- //如果表名是Supplier,則根據city值設定向哪個場地發(fā)送命令
- publicArrayListSetInsertSite(stringsqlText){
- }
- //生成解析后的insert命令列表
- publicArrayListSetInsertList(stringsqlText){
- }
Delete 操作——
向各個場地發(fā)送,通過定義數據庫中表的關系及約束來保證完整性和一致性,如果刪除命令不成功,則返回異常信息,否則,返回各個場地成功執(zhí)行命令影響的記錄數目。
Select 操作——
- //得到sql語句的類型
- publicstringGetSqlType(stringsqlText)//typeofSQLstatements{
- }
- //得到select語句要查詢的表名
- publicstringGetSelectTableName(stringsqlText){
- }
- //得到select語句中的where子句
- publicstringGetWhereClause(stringsqlText){
- }
- //得到查詢條件中的字段名
- publicstringGetSelectField(stringsqlText){
- }
- //得到分片依據,返回Scity的值
- publicstringGetSelectCityValue(stringsqlText){
- }
- //設定select語句經解析后的格式
- publicArrayListSetSelectList(stringsqlText){
- }
- //如果沒有分片信息,則向3個場地都發(fā)送命令
- publicArrayListSendToAllSite(stringsqlText){
- }
第6章 結論
.NET遠程處理框架提供的一項強大的技術,利用它可以使位于任何位置的應用程序互相通信,這些應用程序可能在同一臺計算機上運行,也可能位于同一局域網中的不同計算機上,或者位于相隔萬里的有巨大差異的網絡中。
使用.NET Remoting技術結合ADO.Net能夠高效、可靠地解決這兩方面的問題。具體表現為,在C#中通過使用.Net遠程處理框架能夠方便地解決數據、命令遠程傳遞問題;C#通過ADO.Net對數據庫進行操作,使分布式數據庫系統(tǒng)中對數據庫的各種操作變得高效、可靠,同時易于解決數據一致性問題。
由于時間關系,程序中仍有部分bug,將在下一步繼續(xù)完善,而且,還應進一步完善數據字典,使程序結構更加清晰,增強可擴充性。
【編輯推薦】