程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 基於.NET平台的分層架構實戰(七-外一篇)—對數據訪問層第一種實現(Access+

基於.NET平台的分層架構實戰(七-外一篇)—對數據訪問層第一種實現(Access+

編輯:關於.NET

基於.NET平台的分層架構實戰(七-外一篇)—對數據訪問層第一種實現(Access+SQL)的重構

昨天的文章基於.NET平台的分層架構實戰(七)——數據訪問層的第一種實現:Access+SQL發布後,很多朋友對我的程序提出了意見和建議,在這裡先謝謝你們!!!尤其是金色海洋(jyk),對我的程序提出了很多建設性的意見。

我大體總結了一下,昨天程序的主要缺點有:

1.Connection對象沒有關閉

2.DataReader對象沒有關閉

3.相似代碼太多,造成代碼冗余。

其中第一點問題,目前還沒有太好的解決方案,主要是因為Connection一旦關閉,DataReader就無法讀取了。而且,Connection對象應該會自動在適當的時候關閉(通過觀察臨時文件得出),並且在實際運行時並無影響(在功能上),所以這裡沒有專門解決。而針對後面兩個問題,我使用了如下解決方案。

對於關閉DataReader的方法,實現起來很簡單,在finally裡將他關閉就行了。關鍵是如何去處冗余代碼。

經過我的分析,數據訪問層的操作可以分為三類:不返回數據,返回單個實體類,返回實體類集合。我將這三種操作的公共部分抽出,寫成三個方法放在AccessDALHelper裡,類型不同的問題使用泛型解決。

這樣做有一個難題,就是不同實體在由DataReader轉化為實體類時的代碼很不一樣,無法抽出。這裡,我使用了Strategy模式解決。具體做法是:首先定義一個由DataReader轉換為實體類的策略接口,然後為不同的實體編寫不同的轉換策略,示意圖如下:

可以看出,所有轉換策略都要實現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[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為例,看一下簡化後的數據訪問層實現:

AdminDAL.cs:

AdminDAL1using 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}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved