好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

对数据访问层第一种实现(Acc+SQL)的重构

昨天的文章基于.NET平台的分层架构实战(七) 数据 访问 层的 第一 种 实现 :Access+SQL发布后,很多朋友对我的程序提出了意见和建议,在这里先谢谢你们!!!尤其是金色海洋(jyk),对我的程序提出了很多建设性的意见。 我大体总结了一下,昨天程序的主要

昨天的文章基于.NET平台的分层架构实战(七)—— 数据 访问 层的 第一 种 实现 :Access+SQL发布后,很多朋友对我的程序提出了意见和建议,在这里先谢谢你们!!!尤其是 金色海洋(jyk),对我的程序提出了很多建设性的意见。

我大体总结了一下,昨天程序的主要缺点有:
1.Connection对象没有关闭
2.DataReader对象没有关闭
3.相似代码太多,造成代码冗余。

其中 第一 点问题,目前还没有太好的解决方案,主要是因为Connection一旦关闭,DataReader就无法读取了。而且,Connection对象应该会自动在适当的时候关闭(通过观察临时文件得出),并且在实际运行时并无影响(在功能上),所以这里没有专门解决。而针对后面两个问题,我使用了如下解决方案。

对于关闭DataReader的方法, 实现 起来很简单,在 finally 里将他关闭就行了。关键是如何去处冗余代码。

经过我的分析, 数据 访问 层的操作可以分为三类:不返回 数据 ,返回单个实体类,返回实体类集合。我将这三种操作的公共部分抽出,写成三个方法放在AccessDALHelper里,类型不同的问题使用泛型解决。

这样做有一个难题,就是不同实体在由DataReader转化为实体类时的代码很不一样,无法抽出。这里,我使用了 Strategy模式解决。具体做法是:首先定义一个由DataReader转换为实体类的策略接口,然后为不同的实体编写不同的转换策略,示意图如下:

可以看出,所有转换策略都要 实现 IDataReaderToEntityStrategy接口,并且每个策略都有一个自组合,这是以为他们都要 实现 Singleton模式。而AccessDALHelper与具体策略无关,仅与接口耦合。

下面来看一下具体代码:

首先是IDataReaderToEntityStrategy接口
IDataReaderToEntityStrategy

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> 1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Data;
5 using System.Data.OleDb;
6
7 namespace NGuestBook.AccessDAL
8 {
9 /**/ ///
10 /// 由DataReader转换成实体类的策略接口
11 ///
12 public interface IDataReaderToEntityStrategy T >
13 {
14 /**/ ///
15 /// 将DataReader转换为实体类,采用泛型
16 ///
17 /// 包含 数据 的DataReader对象
18 /// 实体类
19 T DataReaderToEntity(OleDbDataReader dataReader);
20 }
21 }

然后以Admin为例,看一下策略的具体 实现 :

1 using System;
2 using System.Collections.Generic;
3 using System.Web;
4 using System.Web.Caching;
5 using System.Configuration;
6 using System.Data;
7 using System.Data.OleDb;
8 using NGuestBook.Utility;
9
10 namespace NGuestBook.AccessDAL
11 {
12 /**/ ///
13 /// Access 数据 库操作助手
14 ///
15 public sealed class AccessDALHelper
16 {
17 /**/ ///
18 /// 读取Access 数据 库的连接字符串
19 /// 首先从缓存里读取,如果不存在则到配置文件中读取,并放入缓存
20 ///
21 /// Access 数据 库的连接字符串
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 /**/ ///
42 /// 执行SQL语句并且不返回任何值
43 ///
44 /// 所执行的SQL命令
45 /// 参数集合
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 /**/ ///
62 /// 执行SQL语句并返回包含查询结果的DataReader
63 ///
64 /// 所执行的SQL命令
65 /// 参数集合
66 ///
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 /**/ ///
85 /// 执行不需要返回 数据 的操作
86 ///
87 /// SQL命令
88 /// 参数
89 /// 是否成功
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 /**/ ///
104 /// 执行返回单个实体类的操作
105 ///
106 /// 实体类类型
107 /// SQL命令
108 /// 参数
109 /// DataReader到实体类的转换策略
110 /// 实体类
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 /**/ ///
135 /// 执行返回实体类集合的操作
136 ///
137 /// 实体类类型
138 /// SQL命令
139 /// 参数
140 /// DataReader到实体类的转换策略
141 /// 实体类
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 &

查看更多关于对数据访问层第一种实现(Acc+SQL)的重构的详细内容...

  阅读:31次