这篇文章讨论如何在c#中实现3层架构,使用MS Access数据库存储数据。在此,我在3层架构中实现一个小型的可复用的组件保存客户数据。并提供添加,更新,查找客户数据的功能。

  背景

  首先,我介绍一些3层架构的理论知识。简单说明:什么是3层架构?3层架构的优点是什么?

  什么是3层架构?

  3层架构是一种“客户端-服务器”架构,在此架构中用户接口,商业逻辑,数据保存以及数据访问被设计为独立的模块。主要有3个层面,第一层(表现层,GUI层),第二层(商业对象,商业逻辑层),第三层(数据访问层)。这些层可以单独开发,单独测试。

  为什么要把程序代码分为3层。把用户接口层,商业逻辑层,数据访问层分离有许多的优点。

  在快速开发中重用商业逻辑组件,我们已经在系统中实现添加,更新,删除,查找客户数据的组件。这个组件已经开发并且测试通过,我们可以在其他要保存客户数据的项目中使用这个组件。

  系统比较容易迁移,商业逻辑层与数据访问层是分离的,修改数据访问层不会影响到商业逻辑层。系统如果从用SQL Server存储数据迁移到用Oracle存储数据,并不需要修改商业逻辑层组件和GUI组件

  系统容易修改,假如在商业层有一个小小的修改,我们不需要在用户的机器上重装整个系统。我们只需要更新商业逻辑组件就可以了。

  应用程序开发人员可以并行,独立的开发单独的层。

  代码

  这个组件有3层,第一个层或者称为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, System.EventArgs e){try    {        cus = new BOCustomer();        cus.cusID=txtID.Text.ToString();        cus.LName = txtLName.Text.ToString();        cus.FName = txtFName.Text.ToString();        cus.Tel= txtTel.Text.ToString();        cus.Address = txtAddress.Text.ToString();        cus.Add();    }catch(Exception err)    {        MessageBox.Show(err.Message.ToString());    }}//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, System.EventArgs e){try    {        String cusID = txtID.Text.ToString();        BOCustomer thisCus = new BOCustomer();        DataSet ds = thisCus.Find(cusID);        DataRow row;        row = ds.Tables[0].Rows[0];//via loopingforeach(DataRow rows in ds.Tables[0].Rows )            {                txtFName.Text = rows["CUS_F_NAME"].ToString();                txtLName.Text = rows["CUS_L_NAME"].ToString();                txtAddress.Text = rows["CUS_ADDRESS"].ToString();                txtTel.Text = rows["CUS_TEL"].ToString();            }    }catch (Exception err)        {            MessageBox.Show(err.Message.ToString());        }}//this function used to update the customer details. private void cmdUpdate_Click(object sender, System.EventArgs e)    {try    {        cus = new BOCustomer();        cus.cusID=txtID.Text.ToString();        cus.LName = txtLName.Text.ToString();        cus.FName = txtFName.Text.ToString();        cus.Tel= txtTel.Text.ToString();        cus.Address = txtAddress.Text.ToString();        cus.Update();    }catch(Exception err)    {        MessageBox.Show(err.Message.ToString());    }}

  商业逻辑层

  下面是商业逻辑层的所有代码,主要包括定义customer对象的属性。但这仅仅是个虚构的customer对象,如果需要可以加入其他的属性。商业逻辑层还包括添加,更新,查找,等方法。

  商业逻辑层是一个中间层,处于GUI层和数据访问层中间。他有一个指向数据访问层的引用cusData = new DACustomer().而且还引用了System.Data名字空间。商业逻辑层使用DataSet返回数据给GUI层。

using System;using System.Data;namespace _3tierarchitecture{/// Summary description for BOCustomer.     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();                }   /// /// Property FirstName (String)///                 public String FName                 {get                            {return this.fName;                            }set                    {try                            {this.fName = value;if (this.fName == "")                                {throw new Exception("Please provide first name ...");                                }                            }catch(Exception e)                            {throw new Exception(e.Message.ToString());                            }                    }                }/// Property LastName (String)                public String LName                {get                    {return this.lName;                    }set                    {//could be more checkings here eg revmove ' chars//change to proper case//blah blah                        this.lName = value;if (this.LName == "")                        {throw new Exception("Please provide name ...");                        }                    }                }     /// Property Customer ID (String)                public String cusID                    {get                        {return this.cusId;                        }set                        {this.cusId = value;if (this.cusID == "")                            {throw new Exception("Please provide ID ...");                            }                        }                    }/// Property Address (String)                public String Address                {get                    {return this.address;                    }set                    {this.address = value;if (this.Address == "")                        {throw new Exception("Please provide address ");                        }                    }                }/// /// Property Telephone (String)///                 public String Tel                {get                    {return this.tel;                    }set                    {this.tel = value;if (this.Tel == "")                        {throw new Exception("Please provide Tel ...");                        }                    }                }/// /// Function Add new customer. Calls /// the function in Data layer.///                 public void Add()                {                    cusData.Add(this);                }/// /// Function Update customer details. /// Calls the function in Data layer.///                 public void Update()                 {                    cusData.Update(this);                }/// /// 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.                public DataSet Find(String str)                 {if (str == "")throw new Exception("Please provide ID to search");                    DataSet data = null;                    data = cusData.Find(str);return data;                }    }}

  数据访问层

  数据层包括处理MS Access数据库的细节。所有这些细节都是透明的,不会影响到商业逻辑层。数据访问层有个指向商业逻辑层的引用BOCustomer cus。为了应用方便并且支持其他数据库。

using System;using System.Data.OleDb;using System.Data;namespace _3tierarchitecture{/// Summary description for DACustomer.         public class DACustomer        {private OleDbConnection cnn;//change connection string as per the //folder you unzip the files                private const string CnnStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data " +"Source= D:\\Rahman_Backup\\Programming\\" + "Csharp\\3tierarchitecture\\customer.mdb;";//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(str,cnn);//execute connection                        cmd.ExecuteNonQuery();// 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 + " = '" + cus.LName + "'" +", " + cus_FName + " = '" + cus.FName + "'" +", " + cus_Address + " = '" + cus.Address + "'" +", " + cus_Tel + " = '" + cus.Tel + "'" +" where cus_ID = '" + cus.cusID + "'";                        OleDbCommand cmd = new OleDbCommand(selectStr,cnn);                        cmd.ExecuteNonQuery();                            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(selectStr,cnn);                            ds = new DataSet();                            da.Fill(ds,thisTable);                            CloseCnn();                                          }catch(Exception e)                        {                            String Str = e.Message;                        }return ds;                    }private void OpenCnn()                    {// initialise connection                        String cnnStr = CnnStr;                        cnn = new OleDbConnection(cnnStr);// open connection                        cnn.Open();                    }private void CloseCnn()                    {// 5- step five                        cnn.Close();                    }       // 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 ( '" + cus.cusID + "' , '" + cus.LName + "' , '" + cus.FName + "' , '" + cus.Address + "' , '" + cus.Tel + "' )";                        insertStr = strTable + strFields + strValues;          return insertStr;                              }        }}

转载于:https://www.cnblogs.com/waw/archive/2011/08/29/2157083.html

艾伟_转载:在C#中实现3层架构相关推荐

  1. 艾伟_转载:C#中的委托和事件-抛砖引玉

    最近在学习委托和事件,在书店里面看了好多书,但是都是迷迷的-- 今天在博客园里面看到了 张子阳 所写的博客C#中的委托和事件:http://www.tracefact.net/CSharp-Progr ...

  2. 艾伟_转载:[一步一步MVC]第五回:让TagBuilder丰富你的HtmlHelper

    本系列文章导航 [一步一步MVC]第一回:使用ActionSelector控制Action的选择 [一步一步MVC]第二回:还是ActionFilter,实现对业务逻辑的统一Authorize处理 [ ...

  3. 艾伟_转载:探索.Net中的委托

    废话 我本来以为委托很简单,本来只想简简单单的说说委托背后的东西,委托的使用方法.原本只想解释一下那句:委托是面向对象的.类型安全的函数指针.可没想到最后惹出一堆的事情来,越惹越多,罪过,罪过.本文后 ...

  4. 艾伟_转载:.NET 4.0中数组的新增功能

    1.两数组是否"相等"? 在实际开发中,有时我们需要比对两个数组是否拥有一致的元素,例如,以下两个数组由于拥有相同的元素,因此被认为是相等的: int[] arr1 = new i ...

  5. 艾伟_转载:使用LINQ to SQL更新数据库(中):几种解决方案

    在前一篇文章中,我提出了在使用LINQ to SQL进行更新操作时可能会遇到的几种问题.其实这并不是我一个人遇到的问题,当我在互联网上寻找答案时,我发现很多人都对这个话题发表过类似文章.但另我无法满足 ...

  6. 艾伟_转载:VS 2010 和 .NET 4.0 系列之《在ASP.NET 4 Web Forms中实现URL导向》篇

    本系列文章导航 VS 2010 和 .NET 4.0 系列之<ASP.NET 4 中的SEO改进 >篇 VS 2010 和 .NET 4.0 系列之<干净的Web.Config文件 ...

  7. 艾伟_转载:学习 ASP.NET MVC (第五回)理论篇

    本系列文章导航 学习 ASP.NET MVC (第一回)理论篇 学习 ASP.NET MVC (第二回)实战篇 学习 ASP.NET MVC (第三回)实战篇 学习 ASP.NET MVC (第四回) ...

  8. 艾伟_转载:C#语言基础常见问题汇总

    概述 1.什么是C#? C#是Microsoft公司设计的一种编程语言.它松散地基于C/C++,并且有很多方面和Java类似. Microsoft是这样描述C#的:"C#是从C和C++派生来 ...

  9. 艾伟_转载:从ASP.NET的PHP执行速度比较谈起

    上星期我在InfoQ发表了一篇新闻,对Joe Stagner在博客上发表的三篇关于ASP.NET与PHP性能对比的文章进行了总结.写新闻其实挺不爽的,因为不能夹杂个人的看法,只能平铺直叙陈述事实.当然 ...

  10. 艾伟_转载:.NET设计模式:观察者模式(Observer Pattern)

    概述 在软件构建过程中,我们需要为某些对象建立一种"通知依赖关系" --一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知.如果这样的依赖关系过于紧密,将 ...

最新文章

  1. Geospark从Shapefile中加载RDD
  2. 为数据赋能:腾讯TDSQL分布式金融级数据库前沿技术
  3. 高清、免版权美图资源大全
  4. B 站神曲 damedane:精髓在于换脸,五分钟就能学会
  5. 入侵sql serve 后拿服务器_quot;条条大路quot;拿webshell
  6. android 美团滑动停止,cc美团 滑动删除(SwipeListView)
  7. jQuery.unique引发一个血案
  8. share 接口的使用
  9. 安装nvm下载node,npm以及配置的全过程。解析npm下载包使用 -v指令 发现下载的包不存在的原因。
  10. 如何获得免费卡巴斯基激活码?
  11. java 图片压缩100k_Java 图片压缩至指定大小
  12. win10下安装PyCharm以及激活
  13. 二 不插SIM卡的GPRS模组-AIR202通过AT指令链接阿里云
  14. WhatsApp群发系统-SendWS拓客系统功能后台介绍(五):WhatsApp筛号群发,群发超链
  15. HTML5小白长成记(5) ---img嵌入图片
  16. Android客户端与PC服务器通过socket进行交互实例
  17. 旅行青蛙南の旅旅行券_旅行时查找WiFi
  18. python中main.py是什么意思_关于python:什么是__main__.py?
  19. java中strictfp么意思_java中的strictfp的作用
  20. 高并发系统高可用设计方案(一)

热门文章

  1. 命令前加./ ,在后台运行程序 linux批处理 linux自动运行程序
  2. Android 调整控件位置和大小(以textView为例,并设置字体与背景颜色)
  3. 【逆元】HDU-1576
  4. 2015软件测试面试题第三篇
  5. 网页制作初期,必须的东西
  6. R语言绘制流程图(二)
  7. R 语言之数据分析高级方法「GLM 广义线性模型」
  8. 《C#图解教程》读书笔记之五:委托和事件
  9. 分享一个vue项目“脚手架”项目的实现步骤
  10. 在IAR下移植CC2650 contiki工程