对数据访问层第一种实现(Acc SQL)的重构_.Net教程
推荐:asp.net基础知识介绍在这个专题里我们将介绍asp.net,Asp.net又叫asp ,他不是asp的简单升级,而是microsoft推出的新一代Active Server Pages。ASP.net是微软发展的新的体系结.NET的一部分,其中全新的技术架构会让
昨天的文章基于.NET平台的分层架构实战(七)——数据访问层的第一种实现:Access SQL发布后,很多朋友对我的程序提出了意见和建议,在这里先谢谢你们!!!尤其是 金色海洋(jyk),对我的程序提出了很多建设性的意见。
我大体总结了一下,昨天程序的主要缺点有:
1.Connection对象没有关闭
2.DataReader对象没有关闭
3.相似代码太多,造成代码冗余。
其中第一点问题,目前还没有太好的解决方案,主要是因为Connection一旦关闭,DataReader就无法读取了。而且,Connection对象应该会自动在适当的时候关闭(通过观察临时文件得出),并且在实际运行时并无影响(在功能上),所以这里没有专门解决。而针对后面两个问题,我使用了如下解决方案。
对于关闭DataReader的方法,实现起来很简单,在finally里将他关闭就行了。关键是如何去处冗余代码。
经过我的分析,数据访问层的操作可以分为三类:不返回数据,返回单个实体类,返回实体类集合。我将这三种操作的公共部分抽出,写成三个方法放在AccessDALHelper里,类型不同的问题使用泛型解决。
这样做有一个难题,就是不同实体在由DataReader转化为实体类时的代码很不一样,无法抽出。这里,我使用了Strategy模式解决。具体做法是:首先定义一个由DataReader转换为实体类的策略接口,然后为不同的实体编写不同的转换策略,示意图如下:
可以看出,所有转换策略都要实现IDataReaderToEntityStrategy接口,并且每个策略都有一个自组合,这是以为他们都要实现Singleton模式。而AccessDALHelper与具体策略无关,仅与接口耦合。
下面来看一下具体代码:
首先是IDataReaderToEntityStrategy接口
IDataReaderToEntityStrategy |
然后以Admin为例,看一下策略的具体实现:
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[i]); 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[i]); 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为例,看一下简化后的数据访问层实现:
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中的状态管理我们在ASP中能够通过cookie、查询字符串、应用程序、对话等轻易地解决这些问题。现在到了ASP.NET环境中,我们仍然可以使用这些功能,只是它们的种类更多了,功能也更强大了。 管理互联网
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP发送Email实例(可带附件)
- js实现广告漂浮效果的小例子
- asp.net Repeater 数据绑定的具体实现
- Asp.Net 无刷新文件上传并显示进度条的实现方法及思路
- Asp.net获取客户端IP常见代码存在的伪造IP问题探讨
- VS2010 水晶报表的使用方法
- ASP.NET中操作SQL数据库(连接字符串的配置及获取)
- asp.net页面传值测试实例代码
- DataGridView - DataGridViewCheckBoxCell的使用介绍
- asp.net中javascript的引用(直接引入和间接引入)
- 三层+存储过程实现分页示例代码
- 相关链接:
- 教程说明:
.Net教程-对数据访问层第一种实现(Acc SQL)的重构。