- 浏览: 659417 次
文章分类
最新评论
基于.NET平台的分层架构实战(七-外一篇)——对数据访问层第一种实现(Access+SQL)的重构
昨天的文章 基于.NET平台的分层架构实战(七)——数据访问层的第一种实现:Access+SQL 发布后,很多朋友对我的程序提出了意见和建议,在这里先谢谢你们!!!尤其是 金色海洋(jyk),对我的程序提出了很多建设性的意见。
我大体总结了一下,昨天程序的主要缺点有:
1.Connection对象没有关闭
2.DataReader对象没有关闭
3.相似代码太多,造成代码冗余。
其中第一点问题,目前还没有太好的解决方案,主要是因为Connection一旦关闭,DataReader就无法读取了。而且,Connection对象应该会自动在适当的时候关闭(通过观察临时文件得出),并且在实际运行时并无影响(在功能上),所以这里没有专门解决。而针对后面两个问题,我使用了如下解决方案。
对于关闭DataReader的方法,实现起来很简单,在finally里将他关闭就行了。关键是如何去处冗余代码。
经过我的分析,数据访问层的操作可以分为三类:不返回数据,返回单个实体类,返回实体类集合。我将这三种操作的公共部分抽出,写成三个方法放在AccessDALHelper里,类型不同的问题使用泛型解决。
这样做有一个难题,就是不同实体在由DataReader转化为实体类时的代码很不一样,无法抽出。这里,我使用了Strategy模式解决。具体做法是:首先定义一个由DataReader转换为实体类的策略接口,然后为不同的实体编写不同的转换策略,示意图如下:
附件: f5.jpg
可以看出,所有转换策略都要实现IDataReaderToEntityStrategy接口,并且每个策略都有一个自组合,这是以为他们都要实现Singleton模式。而AccessDALHelper与具体策略无关,仅与接口耦合。
下面来看一下具体代码:
首先是IDataReaderToEntityStrategy接口
IDataReaderToEntityStrategy.cs:
IDataReaderToEntityStrategy
- 1using System;
- 2using System.Collections.Generic;
- 3using System.Text;
- 4using System.Data;
- 5using System.Data.OleDb;
- 6
- 7namespace NGuestBook.AccessDAL
- 8{
- 9 /**//// <summary>
- 10 /// 由DataReader转换成实体类的策略接口
- 11 /// </summary>
- 12 public interface IDataReaderToEntityStrategy<T>
- 13 {
- 14 /**//// <summary>
- 15 /// 将DataReader转换为实体类,采用泛型
- 16 /// </summary>
- 17 /// <param name="dataReader">包含数据的DataReader对象</param>
- 18 /// <returns>实体类</returns>
- 19 T DataReaderToEntity(OleDbDataReader dataReader);
- 20 }
- 21}
然后以Admin为例,看一下策略的具体实现:
AdminDataReaderToEntityStrategy.cs:
AdminDataReaderToEntityStrategy
- 1using System;
- 2using System.Collections.Generic;
- 3using System.Text;
- 4using System.Data;
- 5using System.Data.OleDb;
- 6using NGuestBook.Entity;
- 7
- 8namespace NGuestBook.AccessDAL
- 9{
- 10 /**//// <summary>
- 11 /// DataReader到实体类的转换策略-管理员
- 12 /// 实现上使用Singleton模式,保证全局唯一实例
- 13 /// </summary>
- 14 public class AdminDataReaderToEntityStrategy : IDataReaderToEntityStrategy<AdminInfo>
- 15 {
- 16 private static AdminDataReaderToEntityStrategy singleInstance = null;
- 17
- 18 /**//// <summary>
- 19 /// 私有化构造函数,保证无法外部实例化
- 20 /// </summary>
- 21 private AdminDataReaderToEntityStrategy() { }
- 22
- 23 /**//// <summary>
- 24 /// 静态方法,用于取得全局唯一实例
- 25 /// </summary>
- 26 /// <returns>全局唯一实例</returns>
- 27 public static AdminDataReaderToEntityStrategy GetInstance()
- 28 {
- 29 if (singleInstance == null)
- 30 {
- 31 singleInstance = new AdminDataReaderToEntityStrategy();
- 32 }
- 33
- 34 return singleInstance;
- 35 }
- 36
- 37 /**//// <summary>
- 38 /// 由DataReader转换到管理员实体类
- 39 /// </summary>
- 40 /// <param name="dataReader">包含数据的DataReader对象</param>
- 41 /// <returns>管理员实体类</returns>
- 42 public AdminInfo DataReaderToEntity(OleDbDataReader dataReader)
- 43 {
- 44 AdminInfo admin = new AdminInfo();
- 45 admin.ID = (int)dataReader["ID"];
- 46 admin.Name = (string)dataReader["Name"];
- 47 admin.Password = (string)dataReader["Password"];
- 48
- 49 return admin;
- 50 }
- 51 }
- 52}
可以看到,这里实现了一个单件模式。下一个,是重构后的AccessDALHelper,增加了三个方法。
AccessDALHelper.cs:
AccessDALHelper
- 1using System;
- 2using System.Collections.Generic;
- 3using System.Web;
- 4using System.Web.Caching;
- 5using System.Configuration;
- 6using System.Data;
- 7using System.Data.OleDb;
- 8using NGuestBook.Utility;
- 9
- 10namespace NGuestBook.AccessDAL
- 11{
- 12 /**//// <summary>
- 13 /// Access数据库操作助手
- 14 /// </summary>
- 15 public sealed class AccessDALHelper
- 16 {
- 17 /**//// <summary>
- 18 /// 读取Access数据库的连接字符串
- 19 /// 首先从缓存里读取,如果不存在则到配置文件中读取,并放入缓存
- 20 /// </summary>
- 21 /// <returns>Access数据库的连接字符串</returns>
- 22 private static string GetConnectionString()
- 23 {
- 24 if (CacheAccess.GetFromCache("AccessConnectionString") != null)
- 25 {
- 26 return CacheAccess.GetFromCache("AccessConnectionString").ToString();
- 27 }
- 28 else
- 29 {
- 30 string dbPath = ConfigurationManager.AppSettings["AccessPath"];
- 31 string dbAbsolutePath = HttpContext.Current.Server.MapPath(dbPath);
- 32 string connectionString = ConfigurationManager.AppSettings["AccessConnectionString"];
- 33
- 34 CacheDependency fileDependency = new CacheDependency(HttpContext.Current.Server.MapPath("Web.Config"));
- 35 CacheAccess.SaveToCache("AccessConnectionString", connectionString.Replace("{DBPath}", dbAbsolutePath), fileDependency);
- 36
- 37 return connectionString.Replace("{DBPath}", dbAbsolutePath);
- 38 }
- 39 }
- 40
- 41 /**//// <summary>
- 42 /// 执行SQL语句并且不返回任何值
- 43 /// </summary>
- 44 /// <param name="SQLCommand">所执行的SQL命令</param>
- 45 /// <param name="parameters">参数集合</param>
- 46 public static void ExecuteSQLNonQuery(string SQLCommand, OleDbParameter[] parameters)
- 47 {
- 48 OleDbConnection connection = new OleDbConnection(GetConnectionString());
- 49 OleDbCommand command = new OleDbCommand(SQLCommand, connection);
- 50
- 51 for (int i = 0; i < parameters.Length; i++)
- 52 {
- 53 command.Parameters.Add(parameters);
- 54 }
- 55
- 56 connection.Open();
- 57 command.ExecuteNonQuery();
- 58 connection.Close();
- 59 }
- 60
- 61 /**//// <summary>
- 62 /// 执行SQL语句并返回包含查询结果的DataReader
- 63 /// </summary>
- 64 /// <param name="SQLCommand">所执行的SQL命令</param>
- 65 /// <param name="parameters">参数集合</param>
- 66 /// <returns></returns>
- 67 public static OleDbDataReader ExecuteSQLDataReader(string SQLCommand, OleDbParameter[] parameters)
- 68 {
- 69 OleDbConnection connection = new OleDbConnection(GetConnectionString());
- 70 OleDbCommand command = new OleDbCommand(SQLCommand, connection);
- 71
- 72 for (int i = 0; i < parameters.Length; i++)
- 73 {
- 74 command.Parameters.Add(parameters);
- 75 }
- 76
- 77 connection.Open();
- 78 OleDbDataReader dataReader = command.ExecuteReader();
- 79 //connection.Close();
- 80
- 81 return dataReader;
- 82 }
- 83
- 84 /**//// <summary>
- 85 /// 执行不需要返回数据的操作
- 86 /// </summary>
- 87 /// <param name="SQLCommand">SQL命令</param>
- 88 /// <param name="parameters">参数</param>
- 89 /// <returns>是否成功</returns>
- 90 public static bool OperateNonData(string SQLCommand, OleDbParameter[] parameters)
- 91 {
- 92 try
- 93 {
- 94 ExecuteSQLNonQuery(SQLCommand, parameters);
- 95 return true;
- 96 }
- 97 catch
- 98 {
- 99 return false;
- 100 }
- 101 }
- 102
- 103 /**//// <summary>
- 104 /// 执行返回单个实体类的操作
- 105 /// </summary>
- 106 /// <typeparam name="T">实体类类型</typeparam>
- 107 /// <param name="SQLCommand">SQL命令</param>
- 108 /// <param name="parameters">参数</param>
- 109 /// <param name="strategy">DataReader到实体类的转换策略</param>
- 110 /// <returns>实体类</returns>
- 111 public static T OperateEntity<T>(string SQLCommand, OleDbParameter[] parameters, IDataReaderToEntityStrategy<T> strategy)
- 112 {
- 113 OleDbDataReader dataReader = ExecuteSQLDataReader(SQLCommand, parameters);
- 114 try
- 115 {
- 116 if (!dataReader.HasRows)
- 117 {
- 118 throw new Exception();
- 119 }
- 120
- 121 dataReader.Read();
- 122 return strategy.DataReaderToEntity(dataReader);
- 123 }
- 124 catch
- 125 {
- 126 return default(T);
- 127 }
- 128 finally
- 129 {
- 130 dataReader.Close();
- 131 }
- 132 }
- 133
- 134 /**//// <summary>
- 135 /// 执行返回实体类集合的操作
- 136 /// </summary>
- 137 /// <typeparam name="T">实体类类型</typeparam>
- 138 /// <param name="SQLCommand">SQL命令</param>
- 139 /// <param name="parameters">参数</param>
- 140 /// <param name="strategy">DataReader到实体类的转换策略</param>
- 141 /// <returns>实体类</returns>
- 142 public static IList<T> OperateEntityCollection<T>(string SQLCommand, OleDbParameter[] parameters, IDataReaderToEntityStrategy<T> strategy)
- 143 {
- 144 OleDbDataReader dataReader = AccessDALHelper.ExecuteSQLDataReader(SQLCommand, null);
- 145 try
- 146 {
- 147 if (!dataReader.HasRows)
- 148 {
- 149 throw new Exception();
- 150 }
- 151
- 152 IList<T> entityCollection = new List<T>();
- 153 int i = 0;
- 154 while (dataReader.Read())
- 155 {
- 156 entityCollection.Add(strategy.DataReaderToEntity(dataReader));
- 157 i++;
- 158 }
- 159
- 160 return entityCollection;
- 161 }
- 162 catch
- 163 {
- 164 return default(IList<T>);
- 165 }
- 166 finally
- 167 {
- 168 dataReader.Close();
- 169 }
- 170 }
- 171 }
- 172}
最后以Admin为例,看一下简化后的数据访问层实现:
AdminDAL.cs:
AdminDAL
- 1using System;
- 2using System.Collections.Generic;
- 3using System.Text;
- 4using System.Data;
- 5using System.Data.OleDb;
- 6using NGuestBook.IDAL;
- 7using NGuestBook.Entity;
- 8
- 9namespace NGuestBook.AccessDAL
- 10{
- 11 public class AdminDAL : IAdminDAL
- 12 {
- 13 /**//// <summary>
- 14 /// 插入管理员
- 15 /// </summary>
- 16 /// <param name="admin">管理员实体类</param>
- 17 /// <returns>是否成功</returns>
- 18 public bool Insert(AdminInfo admin)
- 19 {
- 20 string SQLCommand = "insert into [TAdmin]([Name],[Password]) values(@name,@password)";
- 21 OleDbParameter[] parameters ={
- 22 new OleDbParameter("name",OleDbType.VarChar,20),
- 23 new OleDbParameter("password",OleDbType.VarChar,50)
- 24 };
- 25 parameters[0].Value = admin.Name;
- 26 parameters[1].Value = admin.Password;
- 27
- 28 return AccessDALHelper.OperateNonData(SQLCommand, parameters);
- 29 }
- 30
- 31 /**//// <summary>
- 32 /// 删除管理员
- 33 /// </summary>
- 34 /// <param name="id">欲删除的管理员的ID</param>
- 35 /// <returns>是否成功</returns>
- 36 public bool Delete(int id)
- 37 {
- 38 string SQLCommand = "delete from [TAdmin] where [ID]=@id";
- 39 OleDbParameter[] parameters ={
- 40 new OleDbParameter("id",OleDbType.Integer)
- 41 };
- 42 parameters[0].Value = id;
- 43
- 44 return AccessDALHelper.OperateNonData(SQLCommand, parameters);
- 45 }
- 46
- 47 /**//// <summary>
- 48 /// 更新管理员信息
- 49 /// </summary>
- 50 /// <param name="admin">管理员实体类</param>
- 51 /// <returns>是否成功</returns>
- 52 public bool Update(AdminInfo admin)
- 53 {
- 54 string SQLCommand = "update [TAdmin] set [Name]=@name,[Password]=@password where [ID]=@id";
- 55 OleDbParameter[] parameters ={
- 56 new OleDbParameter("id",OleDbType.Integer),
- 57 new OleDbParameter("name",OleDbType.VarChar,20),
- 58 new OleDbParameter("password",OleDbType.VarChar,50)
- 59 };
- 60 parameters[0].Value = admin.ID;
- 61 parameters[1].Value = admin.Name;
- 62 parameters[2].Value = admin.Password;
- 63
- 64 return AccessDALHelper.OperateNonData(SQLCommand, parameters);
- 65 }
- 66
- 67 /**//// <summary>
- 68 /// 按ID取得管理员信息
- 69 /// </summary>
- 70 /// <param name="id">管理员ID</param>
- 71 /// <returns>管理员实体类</returns>
- 72 public AdminInfo GetByID(int id)
- 73 {
- 74 string SQLCommand = "select * from [TAdmin] where [ID]=@id";
- 75 OleDbParameter[] parameters ={
- 76 new OleDbParameter("id",OleDbType.Integer)
- 77 };
- 78 parameters[0].Value = id;
- 79
- 80 return AccessDALHelper.OperateEntity<AdminInfo>(SQLCommand, parameters, AdminDataReaderToEntityStrategy.GetInstance());
- 81 }
- 82
- 83 /**//// <summary>
- 84 /// 按用户名及密码取得管理员信息
- 85 /// </summary>
- 86 /// <param name="name">用户名</param>
- 87 /// <param name="password">密码</param>
- 88 /// <returns>管理员实体类,不存在时返回null</returns>
- 89 public AdminInfo GetByNameAndPassword(string name, string password)
- 90 {
- 91 string SQLCommand = "select * from [TAdmin] where [Name]=@name and [Password]=@password";
- 92 OleDbParameter[] parameters ={
- 93 new OleDbParameter("name",OleDbType.VarChar,20),
- 94 new OleDbParameter("password",OleDbType.VarChar,50)
- 95 };
- 96 parameters[0].Value = name;
- 97 parameters[1].Value = password;
- 98
- 99 return AccessDALHelper.OperateEntity<AdminInfo>(SQLCommand, parameters, AdminDataReaderToEntityStrategy.GetInstance());
- 100 }
- 101
- 102 /**//// <summary>
- 103 /// 按管理员名取得管理员信息
- 104 /// </summary>
- 105 /// <param name="name">管理员名</param>
- 106 /// <returns>管理员实体类</returns>
- 107 public AdminInfo GetByName(string name)
- 108 {
- 109 string SQLCommand = "select * from [TAdmin] where [Name]=@name";
- 110 OleDbParameter[] parameters ={
- 111 new OleDbParameter("name",OleDbType.VarChar,20)
- 112 };
- 113 parameters[0].Value = name;
- 114
- 115 return AccessDALHelper.OperateEntity<AdminInfo>(SQLCommand, parameters, AdminDataReaderToEntityStrategy.GetInstance());
- 116 }
- 117
- 118 /**//// <summary>
- 119 /// 取得全部管理员信息
- 120 /// </summary>
- 121 /// <returns>管理员实体类集合</returns>
- 122 public IList<AdminInfo> GetAll()
- 123 {
- 124 string SQLCommand = "select * from [TAdmin]";
- 125
- 126 return AccessDALHelper.OperateEntityCollection<AdminInfo>(SQLCommand, null, AdminDataReaderToEntityStrategy.GetInstance());
- 127 }
- 128 }
- 129}
相关推荐
计算机专业毕业设计-ASP.NET+SQL 项目设计软件源码+WORD毕业论文文档合集: 计算机专业毕业设计-ASP+ACCESS仓库即时查询系统毕业设计(源代码+论文).rar 计算机专业毕业设计-ASP+ACCESS出租车管理系统(开题报告+源代码...
ADO.Net助手是一个获取ADO.Net连接字符串(支持ADO.Net助手是一个获取ADO.Net连接字符串(支持Access,SQLite,SQLServer,MySQL和ORACLE),测试SQL命令,存储过程和数据库之间互导数据的辅助软件。ADO.Net助手还可以...
商业编程-源码-魔法单词记忆——DAO访问ACCESS数据库.zip
ADO.Net助手是一个获取ADO.Net连接字符串(支持Access,SQLite,SQLServer,MySQL和ORACLE),测试SQL命令,存储过程和数据库之间互导数据的辅助软件。ADO.Net助手还可以用来以插入SQL语句形式导出导入记录,目前提供了...
ASP.NET源码——汽车配件公司网站(VB.net+Access数据库)源码.zip
新的IO组件在处理磁盘中的文件时,将不必再对文件执行I/O操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件...
Vs2005+Access+Asp.net+Extjs三层架构源码
基于抽象工厂和反射(IOC)的.Net 7层架构项目,方便大家学习和参考
1.整个系统架构 2.通过修改配置文件实现Access数据库与SQLServer数据库之间的切换 3.Access数据库管理员的登录用户:adminAccess,密码:00000 4.SQLServer数据库管理员登录用户:adminSqlServer,密码:00000 5....
asp.net 2.0-实现数据访问(1) ASP.NET 2.0 新特性 .NET 2.0里使用强类型数据创建多层应用 在MastPage中引用脚本资源 2.0正式版中callback的一些变化+使用示例(ASP.NET 2.0) asp.net 2.0 新特性 Visual Web ...
一套基于VS2008+Access+Asp.net+Flex实现的网络硬盘源码程序
随便写的一个ASP.NET 标准三层架构留言本,支持SQL2000和ACCESS两种数据库. 带抽象工厂,学习三层的朋友可以看下,写的比较简单. 后台进入:admin/login.aspx 后台帐号:admin 后台密码:admin888 程序说明:ASP.NET...
程序说明:ASP.NET2.0+SQLSERVER2000 ACCESS 开发。 BLL: 业务层 DALFactory:数据工厂 Utility:数据访问层 IDAL:接口层 Model: 数据实体层 SQLServerDAL: SQL数据层 AccessDAL:Access数据层 Web: 表示层,web项目...
首先,必须严肃脸说明的是,对于普通 Excel 使用者而言,VBA、SQL 以及以 后提及的 ADO 并不是非学不可的,非学不可的...存仓库,进而储存、分析远超 Excel 体积的数据量,本书描述了ADO和VBA喝SQL in Excel平台的运用
实现了网上选课系统,通过该系统,学校不同角色的用户可以通过网路完成选课系统功能:管理员通过该系统实现对学生、教师、课程的添加和维护和学生成绩的维护;教师通过该系统实现查看课程选修情况和录入学生成绩;...
vb.net2010数据库编程基础教程-数据绑定,使用控件方式连接数据库,图文教程
ASP.NET实现SQL和Access数据直接的到导入导出,希望能给大家一点帮助。
asp.net网站专用轻量级数据访问框架 1.集成SqlServer数据访问操作 2.集成Access数据访问操作 3.集成MySql数据访问操作 4.有两个文件夹(1).framework,只是把文件拷贝出来,大家可以把这些文件放到项目的更目录 MySql...
S7-200——PC Access——WinCC的实现方法rar,S7-200——PC Access——WinCC的实现方法