對數(shù)據(jù)訪問層第一種實現(xiàn)(Acc SQL)的重構(gòu)_.Net教程
推薦:asp.net基礎(chǔ)知識介紹在這個專題里我們將介紹asp.net,Asp.net又叫asp ,他不是asp的簡單升級,而是microsoft推出的新一代Active Server Pages。ASP.net是微軟發(fā)展的新的體系結(jié).NET的一部分,其中全新的技術(shù)架構(gòu)會讓
昨天的文章基于.NET平臺的分層架構(gòu)實戰(zhàn)(七)——數(shù)據(jù)訪問層的第一種實現(xiàn):Access SQL發(fā)布后,很多朋友對我的程序提出了意見和建議,在這里先謝謝你們�。�!尤其是 金色海洋(jyk),對我的程序提出了很多建設(shè)性的意見。
我大體總結(jié)了一下,昨天程序的主要缺點有:
1.Connection對象沒有關(guān)閉
2.DataReader對象沒有關(guān)閉
3.相似代碼太多,造成代碼冗余。
其中第一點問題,目前還沒有太好的解決方案,主要是因為Connection一旦關(guān)閉,DataReader就無法讀取了。而且,Connection對象應(yīng)該會自動在適當(dāng)?shù)臅r候關(guān)閉(通過觀察臨時文件得出),并且在實際運行時并無影響(在功能上),所以這里沒有專門解決。而針對后面兩個問題,我使用了如下解決方案。
對于關(guān)閉DataReader的方法,實現(xiàn)起來很簡單,在finally里將他關(guān)閉就行了。關(guān)鍵是如何去處冗余代碼。
經(jīng)過我的分析,數(shù)據(jù)訪問層的操作可以分為三類:不返回數(shù)據(jù),返回單個實體類,返回實體類集合。我將這三種操作的公共部分抽出,寫成三個方法放在AccessDALHelper里,類型不同的問題使用泛型解決。
這樣做有一個難題,就是不同實體在由DataReader轉(zhuǎn)化為實體類時的代碼很不一樣,無法抽出。這里,我使用了Strategy模式解決。具體做法是:首先定義一個由DataReader轉(zhuǎn)換為實體類的策略接口,然后為不同的實體編寫不同的轉(zhuǎn)換策略,示意圖如下:
可以看出,所有轉(zhuǎn)換策略都要實現(xiàn)IDataReaderToEntityStrategy接口,并且每個策略都有一個自組合,這是以為他們都要實現(xiàn)Singleton模式。而AccessDALHelper與具體策略無關(guān),僅與接口耦合。

下面來看一下具體代碼:
首先是IDataReaderToEntityStrategy接口
然后以Admin為例,看一下策略的具體實現(xiàn):
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.AccessDAL11 ![]() ![]() {12 ![]() /**//// <summary>13 /// Access數(shù)據(jù)庫操作助手14 /// </summary>15 public sealed class AccessDALHelper16 ![]() {17 ![]() /**//// <summary>18 /// 讀取Access數(shù)據(jù)庫的連接字符串19 /// 首先從緩存里讀取,如果不存在則到配置文件中讀取,并放入緩存20 /// </summary>21 /// <returns>Access數(shù)據(jù)庫的連接字符串</returns>22 private static string GetConnectionString()23 ![]() {24 if (CacheAccess.GetFromCache("AccessConnectionString") != null)25 ![]() {26 return CacheAccess.GetFromCache("AccessConnectionString").ToString();27 }28 else29 ![]() {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 /// 執(zhí)行SQL語句并且不返回任何值43 /// </summary>44 /// <param name="SQLCommand">所執(zhí)行的SQL命令</param>45 /// <param name="parameters">參數(shù)集合</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 /// 執(zhí)行SQL語句并返回包含查詢結(jié)果的DataReader63 /// </summary>64 /// <param name="SQLCommand">所執(zhí)行的SQL命令</param>65 /// <param name="parameters">參數(shù)集合</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 /// 執(zhí)行不需要返回數(shù)據(jù)的操作86 /// </summary>87 /// <param name="SQLCommand">SQL命令</param>88 /// <param name="parameters">參數(shù)</param>89 /// <returns>是否成功</returns>90 public static bool OperateNonData(string SQLCommand, OleDbParameter[] parameters)91 ![]() {92 try93 ![]() {94 ExecuteSQLNonQuery(SQLCommand, parameters);95 return true;96 }97 catch98 ![]() {99 return false;100 }101 }102 ![]() 103 ![]() /**//// <summary>104 /// 執(zhí)行返回單個實體類的操作105 /// </summary>106 /// <typeparam name="T">實體類類型</typeparam>107 /// <param name="SQLCommand">SQL命令</param>108 /// <param name="parameters">參數(shù)</param>109 /// <param name="strategy">DataReader到實體類的轉(zhuǎn)換策略</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 try115 ![]() {116 if (!dataReader.HasRows)117 ![]() {118 throw new Exception();119 }120 ![]() 121 dataReader.Read();122 return strategy.DataReaderToEntity(dataReader);123 }124 catch125 ![]() {126 return default(T);127 }128 finally129 ![]() {130 dataReader.Close();131 }132 }133 ![]() 134 ![]() /**//// <summary>135 /// 執(zhí)行返回實體類集合的操作136 /// </summary>137 /// <typeparam name="T">實體類類型</typeparam>138 /// <param name="SQLCommand">SQL命令</param>139 /// <param name="parameters">參數(shù)</param>140 /// <param name="strategy">DataReader到實體類的轉(zhuǎn)換策略</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 try146 ![]() {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 catch163 ![]() {164 return default(IList<T>);165 }166 finally167 ![]() {168 dataReader.Close();169 }170 }171 }172 } |
最后以Admin為例,看一下簡化后的數(shù)據(jù)訪問層實現(xiàn):
1 using System;2 using System.Collections.Generic;3 using System.Text;4 using System.Data;5 using System.Data.OleDb;6 using NGuestBook.IDAL;7 using NGuestBook.Entity;8 ![]() 9 namespace NGuestBook.AccessDAL10 ![]() ![]() {11 public class AdminDAL : IAdminDAL12 ![]() {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中的狀態(tài)管理我們在ASP中能夠通過cookie、查詢字符串、應(yīng)用程序、對話等輕易地解決這些問題�,F(xiàn)在到了ASP.NET環(huán)境中,我們?nèi)匀豢梢允褂眠@些功能,只是它們的種類更多了,功能也更強大了。 管理互聯(lián)網(wǎng)
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP發(fā)送Email實例(可帶附件)
- js實現(xiàn)廣告漂浮效果的小例子
- asp.net Repeater 數(shù)據(jù)綁定的具體實現(xiàn)
- Asp.Net 無刷新文件上傳并顯示進度條的實現(xiàn)方法及思路
- Asp.net獲取客戶端IP常見代碼存在的偽造IP問題探討
- VS2010 水晶報表的使用方法
- ASP.NET中操作SQL數(shù)據(jù)庫(連接字符串的配置及獲取)
- asp.net頁面?zhèn)髦禍y試實例代碼
- DataGridView - DataGridViewCheckBoxCell的使用介紹
- asp.net中javascript的引用(直接引入和間接引入)
- 三層+存儲過程實現(xiàn)分頁示例代碼
- 相關(guān)鏈接:
- 教程說明:
.Net教程-對數(shù)據(jù)訪問層第一種實現(xiàn)(Acc SQL)的重構(gòu)
。





}