这篇文章讨论如何在c#中实现层架构使用MS Access数据库存储数据在此我在层架构中实现一个小型的可复用的组件保存客户数据并提供添加更新查找客户数据的功能
背景
首先我介绍一些层架构的理论知识简单说明什么是层架构?层架构的优点是什么?
什么是层架构?
层架构是一种客户端-服务器架构在此架构中用户接口商业逻辑数据保存以及数据访问被设计为独立的模块主要有个层面第一层(表现层GUI层)第二层(商业对象商业逻辑层)第三层(数据访问层)这些层可以单独开发单独测试
为什么要把程序代码分为层把用户接口层商业逻辑层数据访问层分离有许多的优点
在快速开发中重用商业逻辑组件我们已经在系统中实现添加更新删除查找客户数据的组件这个组件已经开发并且测试通过我们可以在其他要保存客户数据的项目中使用这个组件
系统比较容易迁移商业逻辑层与数据访问层是分离的修改数据访问层不会影响到商业逻辑层系统如果从用SQL Server存储数据迁移到用Oracle存储数据并不需要修改商业逻辑层组件和GUI组件
系统容易修改假如在商业层有一个小小的修改我们不需要在用户的机器上重装整个系统我们只需要更新商业逻辑组件就可以了
应用程序开发人员可以并行独立的开发单独的层
代码
这个组件有层第一个层或者称为GUI层用form实现叫做FrmGUI第二层或者称为商业逻辑层叫做BOCustomer是Bussniess Object Customer的缩写最后是第三层或者称为数据层叫做DACustomer是Data Access Customer的缩写为了方便我把三个层编译到一个项目中
用户接口层
下面是用户接口成的一段代码我只选取了调用商业逻辑层的一部分代码
//This function get the details from the user via GUI
//tier and calls the Add method of business logic layer
private void cmdAdd_Click(object sender SystemEventArgs e)
{
try
{
cus = new BOCustomer();
cuscusID=txtIDTextToString();
cusLName = txtLNameTextToString();
cusFName = txtFNameTextToString();
cusTel= txtTelTextToString();
cusAddress = txtAddressTextToString();
cusAdd();
}
catch(Exception err)
{
MessageBoxShow(errMessageToString());
}
}
//This function gets the ID from the user and finds the
//customer details and return the details in the form of
//a dataset via busniss object layer Then it loops through
//the content of the dataset and fills the controls
private void cmdFind_Click(object sender SystemEventArgs e)
{
try
{
String cusID = txtIDTextToString();
BOCustomer thisCus = new BOCustomer();
DataSet ds = thisCusFind(cusID);
DataRow row;
row = dsTables[]Rows[];
//via looping
foreach(DataRow rows in dsTables[]Rows )
{
txtFNameText = rows[CUS_F_NAME]ToString();
txtLNameText = rows[CUS_L_NAME]ToString();
txtAddressText = rows[CUS_ADDRESS]ToString();
txtTelText = rows[CUS_TEL]ToString();
}
}
catch (Exception err)
{
MessageBoxShow(errMessageToString());
}
}
//this function used to update the customer details
private void cmdUpdate_Click(object sender SystemEventArgs e)
{
try
{
cus = new BOCustomer();
cuscusID=txtIDTextToString();
cusLName = txtLNameTextToString();
cusFName = txtFNameTextToString();
cusTel= txtTelTextToString();
cusAddress = txtAddressTextToString();
cusUpdate();
}
catch(Exception err)
{
MessageBoxShow(errMessageToString());
}
}
商业逻辑层
下面是商业逻辑层的所有代码主要包括定义customer对象的属性但这仅仅是个虚构的customer对象如果需要可以加入其他的属性商业逻辑层还包括添加更新查找等方法
商业逻辑层是一个中间层处于GUI层和数据访问层中间他有一个指向数据访问层的引用cusData = new DACustomer()而且还引用了SystemData名字空间商业逻辑层使用DataSet返回数据给GUI层
using System;
using SystemData;
namespace _tierarchitecture
{
/// <SUMMARY>
/// Summary description for BOCustomer
/// </SUMMARY>
public class BOCustomer
{
//Customer properties
private String fName;
private String lName;
private String cusId;
private String address;
private String tel;
private DACustomer cusData;
public BOCustomer()
{
//An instance of the Data access layer!
cusData = new DACustomer();
}
/// <SUMMARY>
/// Property FirstName (String)
/// </SUMMARY>
public String FName
{
get
{
return thisfName;
}
set
{
try
{
thisfName = value;
if (thisfName == )
{
throw new Exception(
Please provide first name );
}
}
catch(Exception e)
{
throw new Exception(eMessageToString());
}
}
}
/// <SUMMARY>
/// Property LastName (String)
/// </SUMMARY>
public String LName
{
get
{
return thislName;
}
set
{
//could be more checkings here eg revmove chars
//change to proper case
//blah blah
thislName = value;
if (thisLName == )
{
throw new Exception(Please provide name );
}
}
}
/// <SUMMARY>
/// Property Customer ID (String)
/// </SUMMARY>
public String cusID
{
get
{
return thiscusId;
}
set
{
thiscusId = value;
if (thiscusID == )
{
throw new Exception(Please provide ID );
}
}
}
/// <SUMMARY>
/// Property Address (String)
/// </SUMMARY>
public String Address
{
get
{
return thisaddress;
}
set
{
thisaddress = value;
if (thisAddress == )
{
throw new Exception(Please provide address );
}
}
}
/// <SUMMARY>
/// Property Telephone (String)
/// </SUMMARY>
public String Tel
{
get
{
return thistel;
}
set
{
thistel = value;
if (thisTel == )
{
throw new Exception(Please provide Tel );
}
}
}
/// <SUMMARY>
/// Function Add new customer Calls
/// the function in Data layer
/// </SUMMARY>
public void Add()
{
cusDataAdd(this);
}
/// <SUMMARY>
/// Function Update customer details
/// Calls the function in Data layer
/// </SUMMARY>
public void Update()
{
cusDataUpdate(this);
}
/// <SUMMARY>
/// Function Find customer Calls the
/// function in Data layer
/// It returns the details of the customer using
/// customer ID via a Dataset to GUI tier
/// </SUMMARY>
public DataSet Find(String str)
{
if (str == )
throw new Exception(Please provide ID to search);
DataSet data = null;
data = cusDataFind(str);
return data;
}
}
}
数据访问层
数据层包括处理MS Access数据库的细节所有这些细节都是透明的不会影响到商业逻辑层数据访问层有个指向商业逻辑层的引用BOCustomer cus为了应用方便并且支持其他数据库
using System;
using SystemDataOleDb;
using SystemData;
namespace _tierarchitecture
{
/// <SUMMARY>
/// Summary description for DACustomer
/// </SUMMARY>
public class DACustomer
{
private OleDbConnection cnn;
//change connection string as per the
//folder you unzip the files
private const string CnnStr =
Provider=MicrosoftJetOLEDB;Data +
Source= D:\\Rahman_Backup\\Programming\\ +
Csharp\\tierarchitecture\\customermdb;;
//local variables
private String strTable=;
private String strFields=;
private String strValues=;
private String insertStr=;
//this needs to be changed based on customer
//table fields Name of the database!
private const String thisTable = tblCustomer;
private const String cus_ID = CUS_ID;
private const String cus_LName = CUS_L_NAME;
private const String cus_FName = CUS_F_NAME;
private const String cus_Tel = CUS_TEL;
private const String cus_Address = CUS_ADDRESS;
public DACustomer()
{
}
public DACustomer(BOCustomer cus)
{
// A reference of the business object class
}
//standard dataset function that adds a new customer
public void Add(BOCustomer cus)
{
String str = BuildAddString(cus);
OpenCnn();
//Open command option cnn parameter is imporant
OleDbCommand cmd = new OleDbCommand(strcnn);
//execute connection
cmdExecuteNonQuery();
// close connection
CloseCnn();
}
//standard dataset function that updates
//details of a customer based on ID
public void Update(BOCustomer cus)
{
OpenCnn();
String selectStr = UPDATE + thisTable +
set + cus_LName + = + cusLName + +
+ cus_FName + = + cusFName + +
+ cus_Address + = + cusAddress + +
+ cus_Tel + = + cusTel + +
where cus_ID = + cuscusID + ;
OleDbCommand cmd = new OleDbCommand(selectStrcnn);
cmdExecuteNonQuery();
CloseCnn();
}
//standard dataset function that finds and
//return the detail of a customer in a dataset
public DataSet Find(String argStr)
{
DataSet ds=null;
try
{
OpenCnn();
String selectStr = select * from + thisTable +
where cus_ID = + argStr + ;
OleDbDataAdapter da =
new OleDbDataAdapter(selectStrcnn);
ds = new DataSet();
daFill(dsthisTable);
CloseCnn();
}
catch(Exception e)
{
String Str = eMessage;
}
return ds;
}
private void OpenCnn()
{
// initialise connection
String cnnStr = CnnStr;
cnn = new OleDbConnection(cnnStr);
// open connection
cnnOpen();
}
private void CloseCnn()
{
// step five
cnnClose();
}
// just a supporting function that builds
// and return the insert string for dataset
private String BuildAddString(BOCustomer cus)
{
// these are the constants as
// set in the top of this module
strTable=Insert into + thisTable;
strFields= ( + cus_ID +
+ cus_LName +
+ cus_FName +
+ cus_Address +
+ cus_Tel + );
//these are the attributes of the
//customer business object
strValues= Values ( + cuscusID +
+ cusLName +
+ cusFName +
+ cusAddress +
+ cusTel + );
insertStr = strTable + strFields + strValues;
return insertStr;
}
}
}