.NET遠(yuǎn)程處理框架詳解
第1章 系統(tǒng)總體結(jié)構(gòu)
1.1 總體結(jié)構(gòu)
系統(tǒng)實現(xiàn)需要部署服務(wù)器端的遠(yuǎn)程對象(即一個DbServerLibrary.dll),服務(wù)器端要注冊通道和該遠(yuǎn)程對象??蛻舳艘獙崿F(xiàn)一個本地查詢的服務(wù)器,同時根據(jù)SQL解析的結(jié)果向各個服務(wù)器發(fā)送命令,并將結(jié)果顯示在客戶端界面,服務(wù)器端可以接受并顯示相應(yīng)的命令。
1.2 關(guān)鍵組件結(jié)構(gòu)
系統(tǒng)結(jié)構(gòu)中關(guān)鍵的組件有遠(yuǎn)程對象,和本地服務(wù)器,實現(xiàn)的功能基本一致。下面以遠(yuǎn)程對象為例,說明組件的實現(xiàn)。遠(yuǎn)程對象在服務(wù)器端解決方案下的庫文件中聲明,通過服務(wù)器端進(jìn)行注冊,客戶端通過TCP通道與服務(wù)器端遠(yuǎn)程對象通信,實現(xiàn)數(shù)據(jù)集的查詢和傳輸。主要的數(shù)據(jù)成員有:SqlConnection(SQL Server數(shù)據(jù)庫的連接對象)、 SqlCommand (SQL命令對象)、SqlDataAdapter(數(shù)據(jù)適配器,填充數(shù)據(jù)集)組件——DbServerLibrary。
第2 章 .NET遠(yuǎn)程處理框架提供的強大技術(shù)
因時間倉促,未實現(xiàn)數(shù)據(jù)字典,所有實驗要求的SQL經(jīng)過解析后,直接通過代碼判斷,向相應(yīng)場地發(fā)送命令。
代碼分為三部分:遠(yuǎn)程對象,服務(wù)器端代碼和客戶端代碼。
其中:遠(yuǎn)程對象部署在各個服務(wù)器端,客戶端除了實現(xiàn)查詢命令的解析和傳送外外,還有一個本地服務(wù)器,進(jìn)行相應(yīng)的本地查詢。
遠(yuǎn)程對象代碼:
- 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;
- }
- }
- }
- }
服務(wù)器端代碼:
- privatevoidfrmSupplierServer_Load(objectsender,System.EventArgse)
- {TcpChannelchan=newTcpChannel(8888);
- ChannelServices.RegisterChannel(chan);
- //注冊提供服務(wù)的遠(yuǎn)程對象
- 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){
- }
- //得到分片依據(jù),返回Scity的值
- publicstringGetSelectCityValue(stringsqlText){
- }
- //設(shè)定select語句經(jīng)解析后的格式
- publicArrayListSetSelectList(stringsqlText){
- }
- //如果沒有分片信息,則向3個場地都發(fā)送命令
- publicArrayListSendToAllSite(stringsqlText){
- }
- //得到insert語句要查詢的表名
- publicstringGetInsertTableName(stringsqlText){
- }
- //根據(jù)插入的表和值,設(shè)定場地:INSERTINTOSupplierVALUES('no','name','city'),returncity
- publicstringGetInsertCityValue(stringsqlText){
- }
- //如果表名是Supplier,則根據(jù)city值設(shè)定向哪個場地發(fā)送命令
- publicArrayListSetInsertSite(stringsqlText){
- }
- //生成解析后的insert命令列表
- publicArrayListSetInsertList(stringsqlText){
- }
- namespaceSupplierClient{
- publicclassLocalServer{
- }
- //返回查詢結(jié)果
- publicDataSetMakeDataSet(stringsqlText){
- }
- //執(zhí)行插入和刪除操作,并返回影響記錄數(shù)
- publicintExecuteSql(stringsqlText){
- }
第4 章 界面
4.1 客戶端
客戶端啟動后,用戶首先在文本框中輸入SQL命令,然后通過解析后向相應(yīng)場地發(fā)送命令,并將返回的結(jié)果集進(jìn)行合并,顯示在界面中,顯示結(jié)果后空白的文本框用來顯示執(zhí)行插入刪除操作時的結(jié)果信息。
4.2 服務(wù)器
服務(wù)器端僅實現(xiàn)對遠(yuǎn)程對象的注冊,因此界面不需要實現(xiàn)功能,只需要在啟動時注冊遠(yuǎn)程對象即可,接收到的客戶端的用戶命令是通過消息框顯示的。如上圖所示。
第5 章 命令處理及核心算法流程
Insert 操作——
- //得到insert語句要查詢的表名
- publicstringGetInsertTableName(stringsqlText){
- }
- //根據(jù)插入的表和值,設(shè)定場地:INSERTINTOSupplierVALUES('no','name','city'),returncity
- publicstringGetInsertCityValue(stringsqlText){
- }
- //如果表名是Supplier,則根據(jù)city值設(shè)定向哪個場地發(fā)送命令
- publicArrayListSetInsertSite(stringsqlText){
- }
- //生成解析后的insert命令列表
- publicArrayListSetInsertList(stringsqlText){
- }
Delete 操作——
向各個場地發(fā)送,通過定義數(shù)據(jù)庫中表的關(guān)系及約束來保證完整性和一致性,如果刪除命令不成功,則返回異常信息,否則,返回各個場地成功執(zhí)行命令影響的記錄數(shù)目。
Select 操作——
- //得到sql語句的類型
- publicstringGetSqlType(stringsqlText)//typeofSQLstatements{
- }
- //得到select語句要查詢的表名
- publicstringGetSelectTableName(stringsqlText){
- }
- //得到select語句中的where子句
- publicstringGetWhereClause(stringsqlText){
- }
- //得到查詢條件中的字段名
- publicstringGetSelectField(stringsqlText){
- }
- //得到分片依據(jù),返回Scity的值
- publicstringGetSelectCityValue(stringsqlText){
- }
- //設(shè)定select語句經(jīng)解析后的格式
- publicArrayListSetSelectList(stringsqlText){
- }
- //如果沒有分片信息,則向3個場地都發(fā)送命令
- publicArrayListSendToAllSite(stringsqlText){
- }
第6章 結(jié)論
.NET遠(yuǎn)程處理框架提供的一項強大的技術(shù),利用它可以使位于任何位置的應(yīng)用程序互相通信,這些應(yīng)用程序可能在同一臺計算機上運行,也可能位于同一局域網(wǎng)中的不同計算機上,或者位于相隔萬里的有巨大差異的網(wǎng)絡(luò)中。
使用.NET Remoting技術(shù)結(jié)合ADO.Net能夠高效、可靠地解決這兩方面的問題。具體表現(xiàn)為,在C#中通過使用.Net遠(yuǎn)程處理框架能夠方便地解決數(shù)據(jù)、命令遠(yuǎn)程傳遞問題;C#通過ADO.Net對數(shù)據(jù)庫進(jìn)行操作,使分布式數(shù)據(jù)庫系統(tǒng)中對數(shù)據(jù)庫的各種操作變得高效、可靠,同時易于解決數(shù)據(jù)一致性問題。
由于時間關(guān)系,程序中仍有部分bug,將在下一步繼續(xù)完善,而且,還應(yīng)進(jìn)一步完善數(shù)據(jù)字典,使程序結(jié)構(gòu)更加清晰,增強可擴充性。
【編輯推薦】