常用连接:
博客首页
随想感悟
编程技术
工程管理
互联网
其他随记
关于
悟心集 | 龙飞的博客
面对自己,寻找真我,战胜自我,摆脱自我
博客园
首页
社区
新随笔
联系
订阅
管理
随笔-80 评论-374 文章-17 trackbacks-6
构建一个.net Remoting 程序(真正的三层结构)
构建一个.net Remoting 程序(真正的三层结构)_突血推荐
!!!
NET Remoting提供了一个功能强大、高效的处理远程对象的方法。我在开发一个电力软件时,由于业务量大,必须用三层结构。实现数据处理(浏览、更新)但是这方面的资料很少。通过摸索我找到的方法。谨献给想用.net开发三层结构数据库应用软件而又苦于找不到方法的C#程序员。
第一步:创建共享库
依次点击“文件”
->
“新创建”
->
“工程”,选择创建一个C# Library,并将其命名为ydglServerLibrary,然后点击OK按钮。这将创建一个我们的.NET Remote客户端和服务器端用来通讯的“共享命令集”。
正面是完整的代码
using
System;
using
System.Runtime ;
using
System.Data.OleDb;
using
System.Data.SqlClient;
using
System.Data;
using
System.Configuration;
namespace
ydglServerClassLibrary1
{
/**/
///
<summary>
///
Class1 的摘要说明。
///
</summary>
public
class
ydglDB:System.MarshalByRefObject
{
private
System.Data.OleDb.OleDbDataAdapter oleDbDataAdapter1;
private
System.Data.OleDb.OleDbCommand oleDbSelectCommand1;
private
System.Data.OleDb.OleDbCommand oleDbInsertCommand1;
private
System.Data.OleDb.OleDbCommand oleDbUpdateCommand1;
private
System.Data.OleDb.OleDbCommand oleDbDeleteCommand1;
private
System.Data.OleDb.OleDbConnection oleDbConnection1;
private
System.ComponentModel.Container components
=
null
;
public
void
InitializeComponent()
{
this
.oleDbDataAdapter1
=
new
System.Data.OleDb.OleDbDataAdapter();
this
.oleDbSelectCommand1
=
new
System.Data.OleDb.OleDbCommand();
this
.oleDbInsertCommand1
=
new
System.Data.OleDb.OleDbCommand();
this
.oleDbUpdateCommand1
=
new
System.Data.OleDb.OleDbCommand();
this
.oleDbDeleteCommand1
=
new
System.Data.OleDb.OleDbCommand();
this
.oleDbConnection1
=
new
System.Data.OleDb.OleDbConnection();
//
//
oleDbDataAdapter1
//
this
.oleDbDataAdapter1.DeleteCommand
=
this
.oleDbDeleteCommand1;
this
.oleDbDataAdapter1.InsertCommand
=
this
.oleDbInsertCommand1;
this
.oleDbDataAdapter1.SelectCommand
=
this
.oleDbSelectCommand1;
this
.oleDbDataAdapter1.TableMappings.AddRange(
new
System.Data.Common.DataTableMapping[]
{
new
System.Data.Common.DataTableMapping(
"
Table
"
,
"
bm_gdfgs
"
,
new
System.Data.Common.DataColumnMapping[]
{
new
System.Data.Common.DataColumnMapping(
"
code
"
,
"
code
"
),
new
System.Data.Common.DataColumnMapping(
"
name
"
,
"
name
"
)}
)}
);
this
.oleDbDataAdapter1.UpdateCommand
=
this
.oleDbUpdateCommand1;
//
//
oleDbSelectCommand1
//
this
.oleDbSelectCommand1.CommandText
=
"
SELECT code, name FROM bm_gdfgs
"
;
this
.oleDbSelectCommand1.Connection
=
this
.oleDbConnection1;
//
//
oleDbInsertCommand1
//
this
.oleDbInsertCommand1.CommandText
=
"
INSERT INTO bm_gdfgs(code, name) VALUES (?, ?); SELECT code, name FROM bm_gdfgs W
"
+
"
HERE (code = ?)
"
;
this
.oleDbInsertCommand1.Connection
=
this
.oleDbConnection1;
this
.oleDbInsertCommand1.Parameters.Add(
new
System.Data.OleDb.OleDbParameter(
"
code
"
, System.Data.OleDb.OleDbType.VarChar,
2
,
"
code
"
));
this
.oleDbInsertCommand1.Parameters.Add(
new
System.Data.OleDb.OleDbParameter(
"
name
"
, System.Data.OleDb.OleDbType.VarChar,
40
,
"
name
"
));
this
.oleDbInsertCommand1.Parameters.Add(
new
System.Data.OleDb.OleDbParameter(
"
Select_code
"
, System.Data.OleDb.OleDbType.VarChar,
2
,
"
code
"
));
//
//
oleDbUpdateCommand1
//
this
.oleDbUpdateCommand1.CommandText
=
"
UPDATE bm_gdfgs SET code = ?, name = ? WHERE (code = ?) AND (name = ? OR ? IS NUL
"
+
"
L AND name IS NULL); SELECT code, name FROM bm_gdfgs WHERE (code = ?)
"
;
this
.oleDbUpdateCommand1.Connection
=
this
.oleDbConnection1;
this
.oleDbUpdateCommand1.Parameters.Add(
new
System.Data.OleDb.OleDbParameter(
"
code
"
, System.Data.OleDb.OleDbType.VarChar,
2
,
"
code
"
));
this
.oleDbUpdateCommand1.Parameters.Add(
new
System.Data.OleDb.OleDbParameter(
"
name
"
, System.Data.OleDb.OleDbType.VarChar,
40
,
"
name
"
));
this
.oleDbUpdateCommand1.Parameters.Add(
new
System.Data.OleDb.OleDbParameter(
"
Original_code
"
, System.Data.OleDb.OleDbType.VarChar,
2
, System.Data.ParameterDirection.Input,
false
, ((System.Byte)(
0
)), ((System.Byte)(
0
)),
"
code
"
, System.Data.DataRowVersion.Original,
null
));
this
.oleDbUpdateCommand1.Parameters.Add(
new
System.Data.OleDb.OleDbParameter(
"
Original_name
"
, System.Data.OleDb.OleDbType.VarChar,
40
, System.Data.ParameterDirection.Input,
false
, ((System.Byte)(
0
)), ((System.Byte)(
0
)),
"
name
"
, System.Data.DataRowVersion.Original,
null
));
this
.oleDbUpdateCommand1.Parameters.Add(
new
System.Data.OleDb.OleDbParameter(
"
Original_name1
"
, System.Data.OleDb.OleDbType.VarChar,
40
, System.Data.ParameterDirection.Input,
false
, ((System.Byte)(
0
)), ((System.Byte)(
0
)),
"
name
"
, System.Data.DataRowVersion.Original,
null
));
this
.oleDbUpdateCommand1.Parameters.Add(
new
System.Data.OleDb.OleDbParameter(
"
Select_code
"
, System.Data.OleDb.OleDbType.VarChar,
2
,
"
code
"
));
//
//
oleDbDeleteCommand1
//
this
.oleDbDeleteCommand1.CommandText
=
"
DELETE FROM bm_gdfgs WHERE (code = ?) AND (name = ? OR ? IS NULL AND name IS NULL
"
+
"
)
"
;
this
.oleDbDeleteCommand1.Connection
=
this
.oleDbConnection1;
this
.oleDbDeleteCommand1.Parameters.Add(
new
System.Data.OleDb.OleDbParameter(
"
Original_code
"
, System.Data.OleDb.OleDbType.VarChar,
2
, System.Data.ParameterDirection.Input,
false
, ((System.Byte)(
0
)), ((System.Byte)(
0
)),
"
code
"
, System.Data.DataRowVersion.Original,
null
));
this
.oleDbDeleteCommand1.Parameters.Add(
new
System.Data.OleDb.OleDbParameter(
"
Original_name
"
, System.Data.OleDb.OleDbType.VarChar,
40
, System.Data.ParameterDirection.Input,
false
, ((System.Byte)(
0
)), ((System.Byte)(
0
)),
"
name
"
, System.Data.DataRowVersion.Original,
null
));
this
.oleDbDeleteCommand1.Parameters.Add(
new
System.Data.OleDb.OleDbParameter(
"
Original_name1
"
, System.Data.OleDb.OleDbType.VarChar,
40
, System.Data.ParameterDirection.Input,
false
, ((System.Byte)(
0
)), ((System.Byte)(
0
)),
"
name
"
, System.Data.DataRowVersion.Original,
null
));
//
//
oleDbConnection1
//
this
.oleDbConnection1.ConnectionString
=
@"
User ID=sa;Data Source=BILLGATES;Tag with column collation when possible=False;Initial Catalog=ydgl;Use Procedure for Prepare=1;Auto Translate=True;Persist Security Info=False;Provider=""SQLOLEDB.1"";Workstation ID=BILLGATES;Use Encryption for Data=False;Packet Size=4096
"
;
//
//
Service1
//
}
public
DataSet Get_bm_gdfgs( )
{
DataSet ds
=
new
DataSet( );
oleDbDataAdapter1.Fill(ds);
return
ds;
}
public
DataSet Update_bm_gdfgs(DataSet ds)
{
if
(ds
!=
null
)
{
oleDbDataAdapter1.Update(ds);
return
ds;
}
else
{
return
null
;
}
}
}
}
请记住,如果得到System.Runtime.Remoting.Channels.Tcp名字空间不存在的信息,请检查是否象上面的代码那样添加了对System.Runtime.Remoting.dll的引用。
编译创建的工程,就会得到一个DLL文件,并可以在其他的工程中使用它。
第二步:创建Server对象
有几种方法可以创建Server对象,最直观的方法是下面的方法:在Visual Studio.NET中,依次点击“文件”
->
“新创建”
->
“工程”,选择创建一个“Windows Application”,并将它命名为ydglServer。
最最重要的是,我们需要添加对刚才在第一步中所创建的DLL文件的应用,该应用程序才能正确地运行。依次点击“工程”
->
“添加引用”,然后通过点击“浏览”按钮添加一个对在第一步中所创建的DLL文件的引用。
为了使用.NET remote功能,必须通过选择“工程”
->
“添加引用”,添加对DLL文件的引用。在.NET标签中选择System.Runtime.Remoting.DLL,然后点击“OK”按钮。然后,需要象我们在第一步中那样添加对System.Runtime.Remoting.dll的引用。
下面的对象相当的简单和直观,我将就真正与.NET remoting相关的3行代码中的每一行进行解释。
TcpServerChannel是.NET remoting支持的二种信道类型中的一种,它将设置我们希望我们的对象对来自哪一个端口的请求进行回应,ChannelServices.RegisterChannel将把该端口号与操作系统中的TCP
/
IP栈绑定。
TcpServerChannel channel
=
new
TcpServerChannel(
9932
);
ChannelServices.RegisterChannel(channel);
另一种可以设置的信道类型是HTTP,只要简单地使用System.Runtime.Remoting.Channels.Http名字空间中的HttpServerChannel对象即可搞定。使用HTTP和TCP信道之间的区别可以简单的归结为:如果应用程序是在局域网上运行,则最好使用TCP信道,因为它的性能要好于HTTP信道;如果应用程序是在互联网上运行,则有时候根据防火墙的配置,HTTP是唯一的选择。需要记住的是,如果使用了防火墙软件,则防火墙应该配置成允许TCP数据流量通过你为对象选择的端口。
RemotingConfiguration.RegisterWellKnownServiceType(
typeof
(ydglDB),
"
ydglDB
"
, WellKnownObjectMode.SingleCall);
这行代码设置了服务中的一些参数和把欲使用的对象名字与远程对象进行绑定,第一个参数是绑定的对象,第二个参数是TCP或HTTP信道中远程对象名字的字符串,第三个参数让容器知道,当有对对象的请求传来时,应该如何处理对象。尽管WellKnownObjectMode.Single对所有的调用者使用一个对象的实例,但它为每个客户生成这个对象的一个实例。
完整的对象代码如下所示:
using
System;
using
System.Drawing;
using
System.Collections;
using
System.ComponentModel;
using
System.Windows.Forms;
using
System.Data;
using
System.Runtime.Remoting;
using
System.Runtime.Remoting.Channels;
using
System.Runtime.Remoting.Channels.Tcp;
using
ydglServerClassLibrary1;
namespace
ydglserver1
{
/**/
///
<summary>
///
Form1 的摘要说明。
///
</summary>
public
class
Form1 : System.Windows.Forms.Form
{
private
System.Windows.Forms.PictureBox pictureBox1;
private
System.Windows.Forms.Button button1;
private
System.Windows.Forms.Button button2;
private
System.Windows.Forms.Button button3;
private
System.Windows.Forms.Label label1;
private
System.Windows.Forms.Label label2;
private
System.Windows.Forms.Label label3;
private
System.Windows.Forms.ComboBox comboBox1;
/**/
///
<summary>
///
必需的设计器变量。
///
</summary>
private
System.ComponentModel.Container components
=
null
;
public
Form1()
{
//
//
Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
//
TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/**/
///
<summary>
///
清理所有正在使用的资源。
///
</summary>
protected
override
void
Dispose(
bool
disposing )
{
if
( disposing )
{
if
(components
!=
null
)
{
components.Dispose();
}
}
base
.Dispose( disposing );
}
Windows 窗体设计器生成的代码
#region
Windows 窗体设计器生成的代码
/**/
///
<summary>
///
设计器支持所需的方法 - 不要使用代码编辑器修改
///
此方法的内容。
///
</summary>
private
void
InitializeComponent()
{
System.Resources.ResourceManager resources
=
new
System.Resources.ResourceManager(
typeof
(Form1));
this
.pictureBox1
=
new
System.Windows.Forms.PictureBox();
this
.button1
=
new
System.Windows.Forms.Button();
this
.button2
=
new
System.Windows.Forms.Button();
this
.button3
=
new
System.Windows.Forms.Button();
this
.label1
=
new
System.Windows.Forms.Label();
this
.label2
=
new
System.Windows.Forms.Label();
this
.label3
=
new
System.Windows.Forms.Label();
this
.comboBox1
=
new
System.Windows.Forms.ComboBox();
this
.SuspendLayout();
//
//
pictureBox1
//
this
.pictureBox1.Image
=
((System.Drawing.Image)(resources.GetObject(
"
pictureBox1.Image
"
)));
this
.pictureBox1.Location
=
new
System.Drawing.Point(
32
,
96
);
this
.pictureBox1.Name
=
"
pictureBox1
"
;
t