如何使用c#创建一个三层的数据库应用程序
1.分析
在我们这个程序中采用如下的层次:web层,业务实体层,数据层。
其中:
业务实体层负责web层与数据层之间的数据交换。
数据层仅仅代表数据库。
web层通过业务实体层来访问数据库。
我们的中间的业务实体层采用webservice.
2.实例
我们通过一个实例来学习三层架构。
(1) 以sql2000为例
建立testuser数据库。
表的sql脚本(在查询分析器中执行即可):
/****** object: table [dbo].[customers] script date: 2004-01-08 0:46:35 ******/
create table [dbo].[customers] (
[customerid] [int] identity (1, 1) not null ,
[customername] [char] (20) not null ,
[addr] [varchar] (50) null ,
[city] [char] (20) null ,
[phone] [char] (20) null ,
[fax] [char] (10) null
) on [primary]
go
/****** object: table [dbo].[users] script date: 2004-01-08 0:46:36 ******/
create table [dbo].[users] (
[id] [int] identity (1, 1) not null ,
[truename] [char] (20) not null ,
[regname] [char] (20) not null ,
[pwd] [char] (10) not null ,
[sex] [char] (2) null ,
[email] [char] (20) null
) on [primary]
go
alter table [dbo].[customers] with nocheck add
constraint [pk_customers] primary key nonclustered
(
[customerid]
) on [primary]
go
alter table [dbo].[users] with nocheck add
constraint [pk_users] primary key nonclustered
(
[id]
) on [primary]
go
(2)创建业务实体层
1.打开vs.net2002,新建一个项目,选asp.net web服务,位置是: http://localhost/mydotnet/tiner/webdata/
2.webservice的代码
using system;
using system.collections;
using system.componentmodel;
using system.data;
using system.data.sqlclient;
using system.diagnostics;
using system.web;
using system.web.services;
using system.web.ui;
using system.web.ui.webcontrols;
using system.web.ui.htmlcontrols;
namespace webdata
{
/// <summary>
/// service1 的摘要说明。
/// </summary>
[webservice (namespace = "http://www.ourfly.com", description = "<font size=4 color=#ff6633><b><br><center>使用c#写的三层架构的程序。</center></b><br><br></font>")]
public class service1 : system.web.services.webservice
{
sqldataadapter myadapter;
string strconn="data source=localhost;initial catalog=testuser;uid=sa;pwd=";
public service1()
{
//codegen:该调用是 asp.net web 服务设计器所必需的
initializecomponent();
}
#region component designer generated code
//web 服务设计器所必需的
private icontainer components = null;
/// <summary>
/// 设计器支持所需的方法 – 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void initializecomponent()
{
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void dispose( bool disposing )
{
if(disposing && components != null)
{
components.dispose();
}
base.dispose(disposing);
}
#endregion
//定义一个私有方法,用来判断用户是否存在
private boolean boolreg(string strregname)
{
boolean strresult;
sqlconnection cn;
sqlcommand cmd;
string strsql;
cn=new sqlconnection(strconn);
cn.open();
strsql="select count(*) from users where regname="+strregname+"";
cmd=new sqlcommand(strsql,cn);
sqldatareader reader = cmd.executereader();
reader.read();
int i = reader.getint32(0);
if (i>0)
{
reader.close();
cn.close ();
strresult= true;
}
else
{
reader.close();
cn.close ();
strresult=false;
}
return strresult;
}
[webmethod(description="完成用户注册功能.")]
public string reguser(string strtruename,string strregname,string strpwd,string strsex,string stremail)
{
string strresult;
sqlconnection cn;
sqlcommand cmd;
//判断用户是否存在
if (boolreg(strregname))
{
strresult="这个用户已经存在,请重新注册";
return strresult;
}
else
{
string strsql;
cn=new sqlconnection(strconn);
cn.open();
strsql="insert into users (truename,regname,pwd,sex,email) values( ";
strsql+=strtruename+",";
strsql+=strregname+",";
strsql+=strpwd+",";
strsql+=strsex+",";
strsql+=stremail+")";
cmd=new sqlcommand(strsql,cn);
try
{
cmd.executenonquery();
cn.close ();
strresult= "用户注册成功";
}
catch(exception e)
{
cn.close ();
strresult="请仔细检查你的输入项";
}
}
return strresult;
}
[webmethod(description="用户登录")]
public string login(string strregname,string strpwd)
{
sqlconnection cn;
sqldataadapter da;
dataset ds;
string strsql,strresult;
strsql="select truename,regname,pwd from users where regname="+strregname+" and pwd="+strpwd+"";
cn=new sqlconnection(strconn);
cn.open();
da=new sqldataadapter(strsql,cn);
ds=new dataset();
da.fill(ds,"users");
if(ds.tables["users"].rows.count>0)
{
strresult= "登录成功";
}
else
{
strresult= "用户名或口令有误或者没有这个用户!请重新输入!";
}
cn.close();
return strresult;
}
[webmethod(description="得到数据集.")]
public dataset getdataset()
{
sqlconnection cn;
cn=new sqlconnection(strconn);
string strsel="select * from customers";
cn.open();
myadapter=new sqldataadapter(strsel,strconn);
dataset ds=new dataset();
myadapter.fill(ds,"customers");
return ds;
}
}
}
运行后如下图所示:
(3)web表现层
打开vs.net2002,新建一个项目,选asp.net web应用程序,位置是: http://localhost/mydotnet/tiner/webapplication1
在解决方案资源管理器中,右键点击”引用”,选择”添加web引用”, 输入http://localhost/mydotnet/tiner/webdata/service1.asmx如下图所示:
添加引用后,如下图:
好了,我们开始写代码,详细代码如下:
using system;
using system.collections;
using system.componentmodel;
using system.data;
using system.drawing;
using system.web;
using system.web.sessionstate;
using system.web.ui;
using system.web.ui.webcontrols;
using system.web.ui.htmlcontrols;
using system.data.sqlclient;
namespace tiner
{
/// <summary>
/// webform1 的摘要说明。
/// </summary>
public class webform1 : system.web.ui.page
{
protected system.web.ui.webcontrols.label label1;
protected system.web.ui.webcontrols.datagrid datagrid1;
protected system.web.ui.webcontrols.label label2;
protected system.web.ui.webcontrols.label label3;
protected system.web.ui.webcontrols.textbox txtusername;
protected system.web.ui.webcontrols.button btlogin;
protected system.web.ui.webcontrols.button btreg;
protected system.web.ui.webcontrols.panel panel1;
protected system.web.ui.webcontrols.label label4;
protected system.web.ui.webcontrols.label label5;
protected system.web.ui.webcontrols.textbox txttruename;
protected system.web.ui.webcontrols.label label6;
protected system.web.ui.webcontrols.label label7;
protected system.web.ui.webcontrols.label label8;
protected system.web.ui.webcontrols.button btok;
protected system.web.ui.webcontrols.textbox txtregname;
protected system.web.ui.webcontrols.textbox txtpwd;
protected system.web.ui.webcontrols.dropdownlist dropdownlistsex;
protected system.web.ui.webcontrols.textbox txtemail;
protected system.web.ui.webcontrols.textbox txtpassword;
string myresult;
dataset ds;
localhost.service1 myservice =new localhost.service1();
private void page_load(object sender, system.eventargs e)
{
// 在此处放置用户代码以初始化页面
if ( !page.ispostback )
{
panel1.visible =false;
}
}
#region web form designer generated code
override protected void oninit(eventargs e)
{
//
// codegen:该调用是 asp.net web 窗体设计器所必需的。
//
initializecomponent();
base.oninit(e);
}
/// <summary>
/// 设计器支持所需的方法 – 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void initializecomponent()
{
this.btlogin.click += new system.eventhandler(this.btlogin_click);
this.btreg.click += new system.eventhandler(this.btreg_click);
this.btok.click += new system.eventhandler(this.btok_click);
this.load += new system.eventhandler(this.page_load);
}
#endregion
private void btreg_click(object sender, system.eventargs e)
{
datagrid1.visible =false;
panel1.visible =true;
}
private void btlogin_click(object sender, system.eventargs e)
{
if (txtusername.text =="" || txtpassword.text=="")
{
label1.text ="请输入用户名或者密码";
return;
}
datagrid1.visible =true;
panel1.visible =false;
myresult=myservice.login(txtusername.text,txtpassword.text ) ;
if (myresult.tostring() =="登录成功")
{
ds=myservice.getdataset();
datagrid1.datasource =ds.tables["customers"];
datagrid1.databind();
}
else
{
label1.text ="用户名或口令有误或者没有这个用户!请重新输入!";
}
}
private void btok_click(object sender, system.eventargs e)
{
myresult=myservice.reguser(txttruename.text,txtregname.text,txtpwd.text,dropdownlistsex.selecteditem.text ,txtemail.text);
if(myresult.tostring()=="用户注册成功" )
{
label1.text ="用户注册成功,可以登录查看信息";
return;
}
else if(myresult.tostring()=="这个用户已经存在,请重新注册" )
{
label1.text ="这个用户已经存在,请重新注册";
return;
}
else
{
label1.text ="用户注册发生错误,请检查每一项";
return;
}
}
}
}
运行启动,输入正确的用户名和密码,点击”登录”按钮,会看到下面的界面:
点击”注册新用户”,出现注册界面,如果注册的用户存在,会产生提示:
总结:
web表示层上完全没有数据库连接操作,它与数据库的连接任务是通过业务层来完成的,这样,程序的结构更加清晰。当然,程序中可以增加其它的层,如:业务规则层等。
如果错误,欢迎大家指教。