C#.NET的N层结构程序开发思路(C# + Access带源代码)
一、准备 设计面向对象软件比较困难,而设计可复用、高扩展、架构安全的面向对象软件就更加困难。下面就自己学习、使用C#.NET开发的一些经验拿出来和大家一块讨论。
示例说明:通过一个简单的数据库系统,了解一下C#.NET的N层设计模式是如何实现的,以及如何提高代码的可复用性、高扩展性、系统安全性。
功能描述:一个简单的图书管理,实现图书信息的增加、修改、删除、检索等功能。
数据库设计: 数据表 t_Book
项目属性及目录结构:
1、建虚拟目录名为Example指向你的项目编辑目录
2、新建asp.net web项目命名为Example
3、设置项目属性:程序集名称、默认命名空间均为“Com.LXJ.Example”
4、目录结构安排:
项目根目录---Book---Business---Book.cs
---Data---BookForAccess.cs
---BookForSql.cs (在讲sql示例时使用)
---BookList.aspx (操作页面,包括:新增、修改、删除、清单功能)
---Buttons (存放图片、按钮等)
---Css--Style.css (样式表)
5、配置web.config文件:配置数据库连接参数
<appSettings>
<!-- connStr参数设置,事例说明: (1)Sql server数据库,例如“server=local;database=test;uid=sa;pwd=;” (2)Access数据库,例如“data\ex.mdb; user id='admin';Jet OLEDB:database password='admin';” --> <add key="connStr" value="DB\Example.mdb; user id='admin';Jet OLEDB:database password='admin';" /> </appSettings> 程序设计开始:
1、按要求建立Access数据库及数据表
2、编写数据库访问、操作的公用类,此类可以复用到以后开发的任何系统中
(1)、新建一个C# 类库项目, 命名为“Com.LXJ”,设置项目属性:程序集名称、默认命名空间均为“Com.LXJ”
(2)、在此项目目录下创建目录Database,新建C# 类文件ConnDbForAccess.cs 在Database目录下。
添加引用:System.Web.dll
(3)、编写ConnDbForAccess.cs 的代码
using System;
using System.Data; using System.Data.OleDb; using System.Web; using System.Web.UI; namespace Com.LXJ.Database { /// <summary> /// conn 的摘要说明。 /// </summary> public class ConnDbForAcccess { /// <summary> /// 连接数据库字符串 /// </summary> private string connectionString; /// <summary>
/// 存储数据库连接(保护类,只有由它派生的类才能访问) /// </summary> protected OleDbConnection Connection; /// <summary>
/// 构造函数:数据库的默认连接 /// </summary> public ConnDbForAcccess() { string connStr; connStr = System.Configuration.ConfigurationSettings.AppSettings["connStr"]; //从web.config配置中读取 connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + HttpContext.Current.Request.PhysicalApplicationPath + connStr;
Connection = new OleDbConnection(connectionString);
} /// <summary>
/// 构造函数:带有参数的数据库连接 /// </summary> /// <param name="newConnectionString"></param> public ConnDbForAcccess(string newConnectionString) { connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + HttpContext.Current.Request.PhysicalApplicationPath + newConnectionString; Connection = new OleDbConnection(connectionString); } /// <summary>
/// 获得连接字符串 /// </summary> public string ConnectionString { get { return connectionString; } } /// <summary> /// 执行SQL语句没有返回结果,如:执行删除、更新、插入等操作 /// </summary> /// <param name="strSQL"></param> /// <returns>操作成功标志</returns> public bool ExeSQL(string strSQL) { bool resultState = false; Connection.Open();
OleDbTransaction myTrans = Connection.BeginTransaction(); OleDbCommand command = new OleDbCommand(strSQL,Connection,myTrans); try { command.ExecuteNonQuery(); myTrans.Commit(); resultState = true; } catch { myTrans.Rollback(); resultState = false; } finally { Connection.Close(); } return resultState; } /// <summary> /// 执行SQL语句返回结果到DataReader中 /// </summary> /// <param name="strSQL"></param> /// <returns>dataReader</returns> private OleDbDataReader ReturnDataReader(string strSQL) { Connection.Open(); OleDbCommand command = new OleDbCommand(strSQL,Connection); OleDbDataReader dataReader = command.ExecuteReader(); Connection.Close(); return dataReader;
} /// <summary>
/// 执行SQL语句返回结果到DataSet中 /// </summary> /// <param name="strSQL"></param> /// <returns>DataSet</returns> public DataSet ReturnDataSet(string strSQL) { Connection.Open(); DataSet dataSet = new DataSet(); OleDbDataAdapter OleDbDA = new OleDbDataAdapter(strSQL,Connection); OleDbDA.Fill(dataSet,"objDataSet"); Connection.Close();
return dataSet; } /// <summary>
/// 执行一查询语句,同时返回查询结果数目 /// </summary> /// <param name="strSQL"></param> /// <returns>sqlResultCount</returns> public int ReturnSqlResultCount(string strSQL) { int sqlResultCount = 0; try
{ Connection.Open(); OleDbCommand command = new OleDbCommand(strSQL,Connection); OleDbDataReader dataReader = command.ExecuteReader(); while(dataReader.Read())
{ sqlResultCount++; } dataReader.Close(); } catch { sqlResultCount = 0; } finally { Connection.Close(); } return sqlResultCount; } }// }// 好了,数据库访问、数据库操作的公用类完成了,详细代码意义大家自己看吧,这些属于C# 语法知识了,现在可以编译生成项目了,编译完后把项目的dll文件Com.LXJ.dll拷贝到Example项目下的bin目录中,然后在项目Example中引入Com.LXJ.dll即可。稍后介绍如何使用它,休息一下,喝口水,呵呵.....
回来了,继续写!
前面的工作都是些辅助性的工作,但是很实用,在你以后的项目中就可以直接使用了。下面就来看一下N层设计中的各层如何实现的,我们这里就以3层(数据层--商务层/业务层--表示层)模式来讲解:
“数据层” 的实现 1、打开“Book/Data/BookForAccess.cs”文件进行代码编写
using System;
using System.Data; using Com.LXJ.Database;
namespace Com.LXJ.Example.Book.Data
{ /// <summary> /// BookForAccess类,记得继承 /// </summary> public class BookForAccess:ConnDbForAcccess { private string sql; //sql语句变量 public BookForAccess()
{ // // TODO: 在此处添加构造函数逻辑 // } /// <summary> /// 新增 /// </summary> /// <param name="bookName">书名</param> /// <returns></returns> public bool Create(string bookName) { sql = ""; sql = sql + " INSERT INTO t_Book(BookName) VALUES('"+bookName+"') "; return ExeSQL(sql); } /// <summary> /// 更新 /// </summary> /// <param name="bookId">编号</param> /// <param name="bookName">书名</param> /// <returns></returns> public bool Update(int bookId,string bookName) { sql = ""; sql = sql + " UPDATE t_Book SET BookName = '"+bookName+"' WHERE BookId = " + bookId; return ExeSQL(sql); } /// <summary> /// 删除 /// </summary> /// <param name="bookId">编号</param> /// <returns></returns> public bool Delete(int bookId) { sql = ""; sql = sql + " DELETE FROM t_Book WHERE BookId = " + bookId; return ExeSQL(sql); } /// <summary> /// 检索一个 /// </summary> /// <param name="bookId">编号</param> /// <returns></returns> public DataRow Retrive(int bookId) { sql = ""; sql = sql + " SELECT * FROM t_Book WHERE BookId = " + bookId; using(DataSet list = ReturnDataSet(sql)) { return list.Tables[0].Rows[0]; } } /// <summary> /// 取得列表 /// </summary> /// <returns></returns> public DataSet List() { sql = ""; sql = sql + " SELECT * FROM t_Book "; using(DataSet list = ReturnDataSet(sql)) { return list; } } }//
}// 2、特殊说明:详细的代码含义这里就不在作详细的解释了
“商务层” 的实现前一篇文章介绍了“数据层”的具体实现,下面介绍“商务层”的具体代码编写:
1、打开“Book/Business/Book.cs”文件,编写代码
using System;
using System.Data; using Com.LXJ.Example.Book.Data;
namespace Com.LXJ.Example.Book.Business
{ /// <summary> /// Book 的摘要说明。 /// </summary> public class Book { private int bookId; private string bookName; public Book() { // // TODO: 在此处添加构造函数逻辑 // } /// <summary> /// 初始化某个记录 /// </summary> /// <param name="_bookId">书编号</param> public Book(int _bookId) { Data.BookForAccess book = new Data.BookForAccess(); DataRow r = book.Retrive(_bookId); bookId = int.Parse(r["BookId"].ToString()); bookName = r["BookName"].ToString(); } /// <summary> /// 新增 /// </summary> /// <returns></returns> public bool Create() { Data.BookForAccess book = new Data.BookForAccess(); return book.Create(bookName); } /// <summary>
/// 更新 /// </summary> /// <returns></returns> public bool Update() { Data.BookForAccess book = new Data.BookForAccess(); return book.Update(bookId,bookName); } /// <summary>
/// 删除 /// </summary> /// <returns></returns> public bool Delete() { Data.BookForAccess book = new Data.BookForAccess(); return book.Delete(bookId); } /// <summary> /// 取得列表 /// </summary> /// <returns></returns> public DataSet List() { Data.BookForAccess book = new Data.BookForAccess(); return book.List(); } /* * 下面设置类的属性 */ /// <summary> /// 书编号 /// </summary> public int BookId { get { return bookId; } set { bookId = value; } } /// <summary>
/// 书名 /// </summary> public string BookName { get { return bookName; } set { bookName = value; } } }//
}// 2、代码含义大家自己研究吧
“表示层”的实现前台显示代码
<!--
<%@ Page language="c#" Codebehind="BookList.aspx.cs" AutoEventWireup="false" Inherits="Com.LXJ.Example.Book.BookList" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>Book Manage System</title> <META http-equiv="Content-Type" content="text/html; charset=gb2312"> <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR"> <meta content="C#" name="CODE_LANGUAGE"> <meta content="JavaScript" name="vs_defaultClientScript"> <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema"> <LINK href="../Css/style.css" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" _fcksavedurl=""../Css/style.css"" type="text/css" rel="stylesheet"> </HEAD> <body bottomMargin="0" leftMargin="5" topMargin="5" rightMargin="5" MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <table width="100%" border="0" cellspacing="0" cellpadding="4"> <tr> <td align="center"> 书名: <asp:TextBox id="tbBookName" runat="server" CssClass="TextBox" MaxLength="50" Width="150px"></asp:TextBox> <asp:Button id="bAdd" runat="server" Text="新增图书"></asp:Button></td> </tr> <tr> <td align="center"> <asp:DataGrid id="dgList" runat="server" Width="100%" AutoGenerateColumns="False" BorderWidth="1px" CellPadding="4" GridLines="Horizontal"> <HeaderStyle Font-Bold="True" BackColor="WhiteSmoke"></HeaderStyle> <Columns> <asp:BoundColumn DataField="BookId" ReadOnly="True" HeaderText="编号"> <HeaderStyle HorizontalAlign="Center"></HeaderStyle> <ItemStyle HorizontalAlign="Center"></ItemStyle> </asp:BoundColumn> <asp:TemplateColumn HeaderText="书名"> <HeaderStyle HorizontalAlign="Center"></HeaderStyle> <ItemStyle HorizontalAlign="Center"></ItemStyle> <ItemTemplate> <asp:Label id=Label1 runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.BookName") %>'> </asp:Label> </ItemTemplate> <EditItemTemplate> <asp:TextBox id=BookName runat="server" Width="150px" MaxLength="50" CssClass="TextBox" Text='<%# DataBinder.Eval(Container, "DataItem.BookName") %>'> </asp:TextBox> </EditItemTemplate> </asp:TemplateColumn> <asp:EditCommandColumn ButtonType="LinkButton" UpdateText="<img border=0 src=../buttons/OK.gif alt=确定>" CancelText="<img border=0 src=../buttons/Cancel.gif alt=取消>" EditText="<img border=0 src=../buttons/Edit.gif alt=修改/编辑>"> <HeaderStyle HorizontalAlign="Center"></HeaderStyle> <ItemStyle HorizontalAlign="Center"></ItemStyle> </asp:EditCommandColumn> <asp:TemplateColumn> <HeaderStyle HorizontalAlign="Center"></HeaderStyle> <ItemStyle HorizontalAlign="Center"></ItemStyle> <ItemTemplate> <asp:LinkButton id="lbDelete" runat="server" Text="<img border=0 src=../buttons/Delete.gif alt=删除>" CausesValidation="false" CommandName="Delete"> <img border="0" src="../buttons/Delete.gif" alt="删除"></asp:LinkButton> </ItemTemplate> </asp:TemplateColumn> </Columns> </asp:DataGrid></td> </tr> </table> </form> </body> </HTML> --> 后台CS编码
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; namespace Com.LXJ.Example.Book
{ /// <summary> /// BookList 的摘要说明。 /// </summary> public class BookList : System.Web.UI.Page { protected System.Web.UI.WebControls.TextBox tbBookName; protected System.Web.UI.WebControls.DataGrid dgList; protected System.Web.UI.WebControls.Button bAdd; private void Page_Load(object sender, System.EventArgs e) { if(!IsPostBack) { BindGrid(); //邦定数据 } } /// <summary> /// 邦定数据 /// </summary> private void BindGrid() { Com.LXJ.Example.Book.Business.Book book = new Com.LXJ.Example.Book.Business.Book(); dgList.DataSource = book.List(); dgList.DataBind(); } #region Web 窗体设计器生成的代码 override protected void OnInit(EventArgs e) { // // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。 // InitializeComponent(); base.OnInit(e); } /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.bAdd.Click += new System.EventHandler(this.bAdd_Click); this.dgList.CancelCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.dgList_CancelCommand); this.dgList.EditCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.dgList_EditCommand); this.dgList.UpdateCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.dgList_UpdateCommand); this.dgList.DeleteCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.dgList_DeleteCommand); this.dgList.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.dgList_ItemDataBound); this.Load += new System.EventHandler(this.Page_Load); }
#endregion private void bAdd_Click(object sender, System.EventArgs e) { string bookName = tbBookName.Text.ToString().Trim(); if(bookName=="") { Response.Write("<Script>"); Response.Write("alert('书名不能空!');"); Response.Write("history.go(-1);"); Response.Write("</Script>"); Response.End(); } Com.LXJ.Example.Book.Business.Book book = new Com.LXJ.Example.Book.Business.Book(); book.BookName = bookName; if(!book.Create()) { Response.Write("<Script>"); Response.Write("alert('新增失败!');"); Response.Write("history.go(-1);"); Response.Write("</Script>"); Response.End(); } //重新加载数据 BindGrid(); tbBookName.Text = ""; } private void dgList_CancelCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{ dgList.EditItemIndex = -1; BindGrid(); } private void dgList_DeleteCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{ int bookId = int.Parse(e.Item.Cells[0].Text.ToString()); Com.LXJ.Example.Book.Business.Book book = new Com.LXJ.Example.Book.Business.Book(); book.BookId = bookId; if(!book.Delete()) { Response.Write("<Script>"); Response.Write("alert('删除失败!');"); Response.Write("history.go(-1);"); Response.Write("</Script>"); Response.End(); } //重新加载数据 BindGrid(); } private void dgList_EditCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{ dgList.EditItemIndex = e.Item.ItemIndex; BindGrid(); } private void dgList_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{ int bookId = int.Parse(e.Item.Cells[0].Text.ToString()); string bookName = ((TextBox)e.Item.Cells[1].FindControl("BookName")).Text.ToString().Trim(); if(bookName=="") { Response.Write("<Script>"); Response.Write("alert('书名不能空!');"); Response.Write("history.go(-1);"); Response.Write("</Script>"); Response.End(); } Com.LXJ.Example.Book.Business.Book book = new Com.LXJ.Example.Book.Business.Book(bookId);
book.BookName = bookName; if(!book.Update()) { Response.Write("<Script>"); Response.Write("alert('修改失败!');"); Response.Write("history.go(-1);"); Response.Write("</Script>"); Response.End(); } //重新加载数据 BindGrid(); } private void dgList_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{ switch(e.Item.ItemType) { case ListItemType.Item: case ListItemType.AlternatingItem: case ListItemType.EditItem: { LinkButton button = (LinkButton)e.Item.FindControl("lbDelete"); button.Attributes.Add(" "javascript:return confirm('删除后不可恢复,确定删除这条记录吗?');"); break; } } } }// }// 结束语
写此文的目的主要是给大家提供一个程序设计思路,尽供参考,不妥之处还望批评指正,以便共同进步。
谁需要源代码请联系我:
|


luoxian
博客统计信息
热门文章
最新评论
友情链接