ORM映射框架總結--數據庫操作庫(精修版)
1. ORM數據庫操作原理
前面已經介紹過了個人ORM映射框架中的三個核心庫:
實體—數據庫 映射特性關系:
http://www.cnblogs.com/qingyuan/archive/2010/04/02/1702998.html
實體分析器:
http://www.cnblogs.com/qingyuan/archive/2010/04/05/1704546.html
Sql 語句生成組建:
http://www.cnblogs.com/qingyuan/archive/2010/04/16/1713658.html
至于這篇文章也就是這四個組件中的最后一個了------- 數據庫操作庫。目前.net 中對于數據庫操作的模板或組件太多了,先不說微軟的Linq to SQL,Linq to Entity, 還有開源組織的Hibernate 克隆版NHibernate,以及前些天突然冒出來的ALinq, 號稱壓過Linq,有時間再研究一下。其實這些看是強大的組件框架,在其外表下面都是如出一轍,他們都是在ADO.NET 中進行的封裝。
不過在這個數據庫操作中,都是ADO.NET進行數據庫操作,但是對于對象的查詢,都是泛化了的類型,也就是說我們不知道具體查詢的是那張表,或者說是查詢結果集是封裝到那個對象,這就是本文要解決的問題。
2. ADO.NET 介紹
感覺在這里進行ADO.NET的講解似乎是多次一舉,我相信ADO.NET是每個asp.net 程序員必會的基本技能。但是這里還是簡單介紹其五個核心對象吧。
Connection: Connection 對象主要是開啟程序和數據庫之間的連結。沒有利用連結對象將數據庫打開,是無法從數據庫中取得數據的。
Command:Command 對象主要可以用來對數據庫發出一些指令,例如可以對數據庫下達查詢、新增、修改、刪除數據等指令,以及呼叫存在數據庫中的預存程序等。
DataAdapter: DataSetCommand 對象主要是在數據源以及DataSet 之間執行數據傳輸的工作,它可以透過Command 對象下達命令后,并將取得的數據放入DataSet 對象中。
DataSet:DataSet 這個對象可以視為一個暫存區(Cache),可以把從數據庫中所查詢到的數據保留起來,甚至可以將整個數據庫顯示出來。DataSet 的能力不只是可以儲存多個Table 而已,還可以透過DataSetCommand 對象取得一些例如主鍵等的數據表結構,并可以記錄數據表間的關聯。DataSet 對象可以說是ADO.NET 中重量級的對象,這個對象架構在DataSetCommand 對象上,本身不具備和數據源溝通的能力。
DataReader: 當我們只需要循序的讀取數據而不需要其它操作時,可以使用DataReader 對象。DataReader對象只是一次一筆向下循序的讀取數據源中的數據,而且這些數據是只讀的,并不允許作其它的操作。因為DataReader 在讀取數據的時候限制了每次只讀取一筆,而且只能只讀,所以使用起來不但節省資源而且效率很好.
老生常談的說了一遍ADO.NET 的五個核心對象,這里主要目的是為了更好的了解此篇文章。我想現在用Linq to SQL , Linq to Entity 的人太多了,或許都忘記了ADO.NET 的基本操作,其實我本人也是如此,一段時間不是用好多忘記了,這里再次復習一遍ADO.NET 能更好的理解此篇文章。
3. 數據庫加載驅動操作接口
該數據庫操作接口很簡單,就是封裝了一些數據庫操作的常用接口和命令,并定義了一些數據庫連接和關閉的方法,并控制了數據庫事務提交和回滾的方法。不過在這里的方法實現中我并沒有對事務進行處理,如果對本文有興趣的人可以在后期的文章中關注,我會對此進行補充。
下面簡單看看數據庫加載驅動接口:

2 * 2010-2-2
3 *
4 * 情 緣
5 *
6 * 數據庫提供加載驅動接口,該接口繼承IDisposable,
7 * 用于釋放對象占用的內存。該接口定義了數據庫鏈接
8 * 語句,鏈接對象,執行命令,適配器模式接口。同時
9 * 還提供了打開數據庫連接和關閉的方法,還有三個方
10 * 法是用于控制數據庫操作事務
11 *
12 * */
13
14 using System;
15 using System.Collections.Generic;
16 using System.Linq;
17 using System.Text;
18 using System.Data;
19
20 namespace CommonData.Data.Core
21 {
22 public interface IDbProvider:IDisposable
23 {
24 /// <summary>
25 /// 數據庫鏈接語句
26 /// </summary>
27 string ConnectionString { get; set; }
28
29 /// <summary>
30 /// 數據庫連接對象
31 /// </summary>
32 IDbConnection Connection { get; set; }
33
34 /// <summary>
35 /// 數據庫操作命令
36 /// </summary>
37 IDbCommand Command { get; set; }
38
39 /// <summary>
40 /// 數據庫操作適配器
41 /// </summary>
42 IDbDataAdapter Adapter { get; set; }
43
44 /// <summary>
45 /// 打開數據庫連接方法
46 /// </summary>
47 void Open();
48
49 /// <summary>
50 /// 關閉數據庫連接方法
51 /// </summary>
52 void Close();
53
54 /// <summary>
55 /// 開始事務控制方法
56 /// </summary>
57 void BeginTransaction();
58
59 /// <summary>
60 /// 事務回滾方法
61 /// </summary>
62 void RollBack();
63
64 /// <summary>
65 /// 事務提交方法
66 /// </summary>
67 void Commit();
68 }
69 }
70
這里數據庫操作的常用對象都是采用的頂層的接口作為屬性。至于為什么使用接口,它的好處已經說的太多了,次數也很多了,這里就不再多說。而public interface IDbProvider:IDisposable 集成這個接口,讓程序自動管理對象,釋放對象占用內存空間。
簡單的看看SQL Server 數據庫加載驅動操作類:

2 * 2010-2-2
3 *
4 * 情 緣
5 *
6 * SQL Server 數據庫操作基本對象
7 * 該類實現了IDbProvider 接口。
8 *
9 * */
10 using System;
11 using System.Collections.Generic;
12 using System.Linq;
13 using System.Text;
14 using System.Data.SqlClient;
15 using System.Data;
16
17 namespace CommonData.Data.Core.SQLCore
18 {
19 public class SqlProvider : IDbProvider
20 {
21 private string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["DataBaseConfig"].ConnectionString;
22 /// <summary>
23 /// 數據庫連接字符串
24 /// </summary>
25 public string ConnectionString
26 {
27 get
28 {
29 if (connectionString == null)
30 {
31 connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["DataBaseConfig"].ConnectionString;
32 }
33 return connectionString;
34 }
35 set
36 {
37 connectionString = value;
38 }
39 }
40
41 private IDbConnection connection = null;
42 /// <summary>
43 /// 數據庫連接對象
44 /// </summary>
45 public IDbConnection Connection
46 {
47 get
48 {
49 if (connection == null)
50 {
51 connection = new SqlConnection(connectionString);
52 }
53 return connection;
54 }
55 set
56 {
57 connection = value;
58 }
59 }
60
61 private IDbCommand command = null;
62 /// <summary>
63 /// 數據庫命令操作對象
64 /// </summary>
65 public IDbCommand Command
66 {
67 get
68 {
69 if (command == null)
70 {
71 command = new SqlCommand();
72 command.Connection = connection;
73 }
74 return command;
75 }
76 set
77 {
78 command = value;
79 }
80 }
81
82 private IDbDataAdapter adapter = null;
83 /// <summary>
84 /// 數據庫適配器對象
85 /// </summary>
86 public IDbDataAdapter Adapter
87 {
88 get
89 {
90 if (adapter == null)
91 {
92 adapter = new SqlDataAdapter(command as SqlCommand);
93 }
94 return adapter;
95 }
96 set
97 {
98 adapter = value;
99 }
100 }
101
102 /// <summary>
103 /// 數據庫事務對象
104 /// </summary>
105 private IDbTransaction transaction = null;
106
107 /// <summary>
108 /// 打開數據庫連接
109 /// </summary>
110 public void Open()
111 {
112 if (connection != null)
113 {
114 connection.Open();
115 }
116 }
117
118 /// <summary>
119 /// 關閉數據庫連接
120 /// </summary>
121 public void Close()
122 {
123 if (connection != null)
124 {
125 connection.Close();
126 }
127 }
128
129 /// <summary>
130 /// 開始事務
131 /// </summary>
132 public void BeginTransaction()
133 {
134 transaction = connection.BeginTransaction();
135 command.Transaction = transaction;
136 }
137
138 /// <summary>
139 /// 事務回滾
140 /// </summary>
141 public void RollBack()
142 {
143 if (transaction != null)
144 {
145 transaction.Rollback();
146 command.Transaction = null;
147 transaction.Dispose();
148 }
149 }
150
151 /// <summary>
152 /// 事務提交
153 /// </summary>
154 public void Commit()
155 {
156 if (transaction != null)
157 {
158 transaction.Commit();
159 command.Transaction = null;
160 transaction.Dispose();
161 }
162 }
163
164 /// <summary>
165 /// 創建數據庫加載驅動
166 /// </summary>
167 /// <returns></returns>
168 public IDbProvider CreateInstance()
169 {
170 return new SqlProvider();
171 }
172
173 /// <summary>
174 /// 釋放內存空間
175 /// </summary>
176 public void Dispose()
177 {
178 GC.SuppressFinalize(this);
179 }
180 }
181 }
182
對于其他的數據庫來說,使用操作的對象和命令都不同,他是它們都提供抽象出來了一個公共接口就是IDbProvider (數據提供加載驅動)。在接口中定義的每個get set 方法都進行了實現實現了一個屬性的封裝,并且提供了唯一對象的變量。(C#中屬性的封裝其實也就是一個get,set方法,所以在接口中能夠這樣定義方法)
4. 數據庫的操作命令
ADO.NET 中查詢數據庫,返回的結果分為多種情況,而數據庫的操作無非就四種情況增刪改查.
而這四種情況又可以分為兩大類:
(1). 數據庫的修改操作: 數據的增加,修改,刪除都對數據進行了操作,都有寫的動作,對數據結構有了變動。
(2). 數據庫的查詢操作:數據庫的查詢,也就是讀取數據,這個操作不會對數據的數據結構進行修改,因此這里可以單獨分為一類。當然一類也就是比較復雜的一類了,查詢的情況會很多不同。
下面是數據庫操作的接口:

2 * 2010-3-5
3 *
4 * 情 緣
5 *
6 * 該接口定義了數據庫操作的各種方法,該接口定義
7 * 工作職責比較明確,只是針對數據的操作,不需要
8 * 管理數據庫的連接等過程。此接口還包含了一個數
9 * 據流和集合類型的轉換的方法定義
10 *
11 * */
12 using System;
13 using System.Collections.Generic;
14 using System.Linq;
15 using System.Text;
16 using System.Data;
17
18 namespace CommonData.Data.Core
19 {
20 public interface IBaseHelper:IDisposable
21 {
22 /// <summary>
23 /// 返回受影響行數
24 /// </summary>
25 /// <param name="provider">數據提供加載驅動</param>
26 /// <param name="sqlString">sql語句</param>
27 /// <returns></returns>
28 int ExecuteNonQuery(IDbProvider provider, string sqlString);
29
30 /// <summary>
31 /// 返回受影響行數
32 /// </summary>
33 /// <param name="provider">數據提供加載驅動</param>
34 /// <param name="sqlString">sql語句</param>
35 /// <param name="isProcedure">是否為存儲過程</param>
36 /// <returns></returns>
37 int ExecuteNonQuery(IDbProvider provider, string sqlString, bool isProcedure);
38
39 /// <summary>
40 /// 返回受影響行數
41 /// </summary>
42 /// <param name="provider">數據提供加載驅動</param>
43 /// <param name="sqlString">sql語句</param>
44 /// <param name="param">sql語句對應參數</param>
45 /// <returns></returns>
46 int ExecuteNonQuery(IDbProvider provider, string sqlString, params IDataParameter[] param);
47
48 /// <summary>
49 /// 返回受影響行數
50 /// </summary>
51 /// <param name="provider">數據提供加載驅動</param>
52 /// <param name="sqlString">sql語句</param>
53 /// <param name="isProcedure">是否為存儲過程,true 為存儲過程</param>
54 /// <param name="param">sql語句對應參數</param>
55 /// <returns></returns>
56 int ExecuteNonQuery(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param);
57
58 /// <summary>
59 /// 返回查詢語句第一行第一列
60 /// </summary>
61 /// <param name="provider">數據提供加載驅動</param>
62 /// <param name="sqlString">sql語句</param>
63 /// <returns></returns>
64 object ExecuteScalar(IDbProvider provider, string sqlString);
65
66 /// <summary>
67 /// 返回查詢語句第一行第一列
68 /// </summary>
69 /// <param name="provider">數據提供加載驅動</param>
70 /// <param name="sqlString">sql語句</param>
71 /// <param name="isProcedure">是否是存儲過程</param>
72 /// <returns></returns>
73 object ExecuteScalar(IDbProvider provider, string sqlString, bool isProcedure);
74
75 /// <summary>
76 /// 返回查詢語句第一行第一列
77 /// </summary>
78 /// <param name="provider">數據提供加載驅動</param>
79 /// <param name="sqlString">sql語句</param>
80 /// <param name="param">sql語句對應輸入參數</param>
81 /// <returns></returns>
82 object ExecuteScalar(IDbProvider provider, string sqlString, params IDataParameter[] param);
83
84 /// <summary>
85 /// 返回查詢語句第一行第一列
86 /// </summary>
87 /// <param name="provider">數據提供加載驅動</param>
88 /// <param name="sqlString">sql語句</param>
89 /// <param name="isProcedure">是否為存儲過程</param>
90 /// <param name="param">sql語句對應輸入參數</param>
91 /// <returns></returns>
92 object ExecuteScalar(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param);
93
94 /// <summary>
95 /// 返回數據只讀游標集
96 /// </summary>
97 /// <param name="provider">數據提供加載驅動</param>
98 /// <param name="sqlString">sql語句</param>
99 /// <returns></returns>
100 IDataReader ExecuteDataReader(IDbProvider provider, string sqlString);
101
102 /// <summary>
103 /// 返回數據只讀游標集
104 /// </summary>
105 /// <param name="provider">數據提供加載驅動</param>
106 /// <param name="sqlString">sql語句</param>
107 /// <param name="isProcedure">是否為存儲過程</param>
108 /// <returns></returns>
109 IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, bool isProcedure);
110
111 /// <summary>
112 /// 返回數據只讀游標集
113 /// </summary>
114 /// <param name="provider">數據提供加載驅動</param>
115 /// <param name="sqlString">sql語句</param>
116 /// <param name="param">sql語句對應輸入參數</param>
117 /// <returns></returns>
118 IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, params IDataParameter[] param);
119
120 /// <summary>
121 /// 返回數據只讀游標集
122 /// </summary>
123 /// <param name="provider">數據提供加載驅動</param>
124 /// <param name="sqlString">sql語句</param>
125 /// <param name="isProcedure">是否為存儲過程</param>
126 /// <param name="param">sql語句對應輸入參數</param>
127 /// <returns></returns>
128 IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param);
129
130 /// <summary>
131 /// 獲得數據表結構集合
132 /// </summary>
133 /// <param name="provider">數據提供加載驅動</param>
134 /// <param name="sqlString">sql語句</param>
135 /// <returns></returns>
136 DataTable ExecuteTable(IDbProvider provider, string sqlString);
137
138 /// <summary>
139 /// 獲得數據表結構集合
140 /// </summary>
141 /// <param name="provider">數據提供加載驅動</param>
142 /// <param name="sqlString">sql語句</param>
143 /// <param name="isProcedure">是否為存儲過程</param>
144 /// <returns></returns>
145 DataTable ExecuteTable(IDbProvider provider, string sqlString, bool isProcedure);
146
147 /// <summary>
148 /// 獲得數據表結構集合
149 /// </summary>
150 /// <param name="provider">數據提供加載驅動</param>
151 /// <param name="sqlString">sql語句</param>
152 /// <param name="param">sql語句對應參數</param>
153 /// <returns></returns>
154 DataTable ExecuteTable(IDbProvider provider, string sqlString, params IDataParameter[] param);
155
156 /// <summary>
157 /// 獲得數據表結構集合
158 /// </summary>
159 /// <param name="provider">數據提供加載驅動</param>
160 /// <param name="sqlString">sql語句</param>
161 /// <param name="isProcedure">是否為存儲過程</param>
162 /// <param name="param">sql語句對應參數</param>
163 /// <returns></returns>
164 DataTable ExecuteTable(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param);
165
166
167
168 /// <summary>
169 /// 根據一個泛型類型獲得實體對象
170 /// </summary>
171 /// <typeparam name="T">泛型類型</typeparam>
172 /// <param name="reader">只讀數據流</param>
173 /// <returns></returns>
174 T ConvertToEntity<T>(IDataReader reader) where T : class ;
175
176 /// <summary>
177 /// 將數據流裝化為對象
178 /// </summary>
179 /// <param name="type">轉化的目標類型</param>
180 /// <param name="reader">只讀數據流</param>
181 /// <returns></returns>
182 object ConvertToEntity(Type type,IDataReader reader);
183
184 /// <summary>
185 /// 根據一個泛型類型查詢一個集合
186 /// </summary>
187 /// <typeparam name="T">泛型類型</typeparam>
188 /// <param name="reader">只讀數據流</param>
189 /// <returns></returns>
190 IList<T> ConvertToList<T>(IDataReader reader) where T : class;
191 }
192 }
193
a).查詢返回受影響的行數
查詢返回受影響的行數,主要針對于數據庫的增刪改三個動作,在這三個動作中都是修改了數據庫的結構。而SQL Server是關系型數據庫,對于數據庫的修改都是以數據行的形式來修改的。所以在對數據庫進行結構修改時,返回的都是受影響的數據行數。
SQL Server返回受影響行數方法實現

2 /// 返回受影響行數
3 /// </summary>
4 /// <param name="provider">數據提供加載驅動</param>
5 /// <param name="sqlString">sql語句</param>
6 /// <returns></returns>
7 public int ExecuteNonQuery(IDbProvider provider, string sqlString)
8 {
9 return ExecuteNonQuery(provider, sqlString, false, null);
10 }
11
12 /// <summary>
13 /// 返回受影響行數
14 /// </summary>
15 /// <param name="provider">數據提供加載驅動</param>
16 /// <param name="sqlString">sql語句</param>
17 /// <param name="isProcedure">是否為存儲過程</param>
18 /// <returns></returns>
19 public int ExecuteNonQuery(IDbProvider provider, string sqlString, bool isProcedure)
20 {
21 return ExecuteNonQuery(provider, sqlString, isProcedure, null);
22 }
23
24 /// <summary>
25 /// 返回受影響行數
26 /// </summary>
27 /// <param name="provider">數據提供加載驅動</param>
28 /// <param name="sqlString">sql語句</param>
29 /// <param name="param">sql語句對應參數</param>
30 /// <returns></returns>
31 public int ExecuteNonQuery(IDbProvider provider, string sqlString, params IDataParameter[] param)
32 {
33 return ExecuteNonQuery(provider, sqlString, false, param);
34 }
35
36 /// <summary>
37 /// 返回受影響行數
38 /// </summary>
39 /// <param name="provider">數據提供加載驅動</param>
40 /// <param name="sqlString">sql語句</param>
41 /// <param name="isProcedure">是否為存儲過程,true 為存儲過程</param>
42 /// <param name="param">sql語句對應參數</param>
43 /// <returns></returns>
44 public int ExecuteNonQuery(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param)
45 {
46 provider.Connection.Open();
47 provider.Command.CommandText = sqlString;
48 if (isProcedure)
49 {
50 provider.Command.CommandType = CommandType.StoredProcedure;
51 }
52 else
53 {
54 provider.Command.CommandType = CommandType.Text;
55 }
56 provider.Command.Parameters.Clear();
57 provider.Command.Parameters.AddRange(param);
58 int line = (int)provider.Command.ExecuteNonQuery();
59 return line;
60 }
從上面的源碼可以看出,其實最終所有的方法都指向了一個方法,而這個方法有個特殊的地方就是bool isProcedure,用此參數可以判斷這個操作的是SQL 語句還是存儲過程。在這個方法中還使用到了一個特殊的參數provider.Command.Parameters,而Parameters集合是沒有AddRange()方法的(而SqlParameters有這個方法),這個方法是使用的一個擴展方法,在.NET3.0 開始擴展方法為.NET 平臺注入了新鮮的血液。讓.NET 平臺變的如此有魅力。
b).查詢返回數據集的第一行第一列
查詢結果返回第一行第一列,我們用得最多的也就是聚合函數的使用了,聚合函數查詢一般也就是查詢返回一個結果。這里也就不再多講解,看看方法實現的代碼

2 /// 返回查詢語句第一行第一列
3 /// </summary>
4 /// <param name="provider">數據提供加載驅動</param>
5 /// <param name="sqlString">sql語句</param>
6 /// <returns></returns>
7 public object ExecuteScalar(IDbProvider provider, string sqlString)
8 {
9 return ExecuteScalar(provider, sqlString, false, null);
10 }
11
12 /// <summary>
13 /// 返回查詢語句第一行第一列
14 /// </summary>
15 /// <param name="provider">數據提供加載驅動</param>
16 /// <param name="sqlString">sql語句</param>
17 /// <param name="isProcedure">是否是存儲過程</param>
18 /// <returns></returns>
19 public object ExecuteScalar(IDbProvider provider, string sqlString, bool isProcedure)
20 {
21 return ExecuteScalar(provider, sqlString, isProcedure, null);
22 }
23
24 /// <summary>
25 /// 返回查詢語句第一行第一列
26 /// </summary>
27 /// <param name="provider">數據提供加載驅動</param>
28 /// <param name="sqlString">sql語句</param>
29 /// <param name="param">sql語句對應輸入參數</param>
30 /// <returns></returns>
31 public object ExecuteScalar(IDbProvider provider, string sqlString, params IDataParameter[] param)
32 {
33 return ExecuteScalar(provider, sqlString, false, param);
34 }
35
36 /// <summary>
37 /// 返回查詢語句第一行第一列
38 /// </summary>
39 /// <param name="provider">數據提供加載驅動</param>
40 /// <param name="sqlString">sql語句</param>
41 /// <param name="isProcedure">是否為存儲過程</param>
42 /// <param name="param">sql語句對應輸入參數</param>
43 /// <returns></returns>
44 public object ExecuteScalar(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param)
45 {
46 provider.Connection.Open();
47 provider.Command.CommandText = sqlString;
48 if (isProcedure)
49 {
50 provider.Command.CommandType = CommandType.StoredProcedure;
51 }
52 else
53 {
54 provider.Command.CommandType = CommandType.Text;
55 }
56 provider.Command.Parameters.Clear();
57 provider.Command.Parameters.AddRange(param);
58 object result = provider.Command.ExecuteScalar();
59 return result;
60 }
c).查詢返回只讀數據流
查詢只讀數據流,返回的就是IDataReader,在ADO.NET 中查詢返回只讀數據流,是一種特別高效的讀取數據的方式。作為.NET程序員我們一般都是使用的SqlDataReader 這個類,其實在程序架構的時候使用其父類接口IdataReader,程序更具靈活性,而這里的IdataReader 其實還有一個更重要的作用。那就是返回結果集合的時候,比如Ilist<T>。對于返回List<T> 結果在后面做介紹。
返回IdataReader 源碼

2 /// 返回數據只讀游標集
3 /// </summary>
4 /// <param name="provider">數據提供加載驅動</param>
5 /// <param name="sqlString">sql語句</param>
6 /// <returns></returns>
7 public IDataReader ExecuteDataReader(IDbProvider provider, string sqlString)
8 {
9 return ExecuteDataReader(provider, sqlString, false, null);
10 }
11
12 /// <summary>
13 /// 返回數據只讀游標集
14 /// </summary>
15 /// <param name="provider">數據提供加載驅動</param>
16 /// <param name="sqlString">sql語句</param>
17 /// <param name="isProcedure">是否為存儲過程</param>
18 /// <returns></returns>
19 public IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, bool isProcedure)
20 {
21 return ExecuteDataReader(provider, sqlString, isProcedure, null);
22 }
23
24 /// <summary>
25 /// 返回數據只讀游標集
26 /// </summary>
27 /// <param name="provider">數據提供加載驅動</param>
28 /// <param name="sqlString">sql語句</param>
29 /// <param name="param">sql語句對應輸入參數</param>
30 /// <returns></returns>
31 public IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, params IDataParameter[] param)
32 {
33 return ExecuteDataReader(provider, sqlString, false, param);
34 }
35
36 /// <summary>
37 /// 返回數據只讀游標集
38 /// </summary>
39 /// <param name="provider">數據提供加載驅動</param>
40 /// <param name="sqlString">sql語句</param>
41 /// <param name="isProcedure">是否為存儲過程</param>
42 /// <param name="param">sql語句對應輸入參數</param>
43 /// <returns></returns>
44 public IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param)
45 {
46 provider.Connection.Open();
47 provider.Command.CommandText = sqlString;
48 if (isProcedure)
49 {
50 provider.Command.CommandType = CommandType.StoredProcedure;
51 }
52 else
53 {
54 provider.Command.CommandType = CommandType.Text;
55 }
56 provider.Command.Parameters.Clear();
57 provider.Command.Parameters.AddRange(param);
58 IDataReader reader = provider.Command.ExecuteReader();
59 return reader;
60 }
d).查詢返回DataTable
DataTable 相當于內存中小型數據庫的表,查詢的數據庫結果將以表的結構保存在內存中,這個是ADO.NET中斷開式數據庫鏈接操作數據的一種有效方式。對于這種方式,查詢數據還是比較方便的,但是對于數據庫的增刪改用DataTable 就比較麻煩了,可以查看ADO.NET數據庫操作的具體內容,這里不做多的介紹。
查詢返回DataTable 結果集源碼

2 /// 獲得數據表結構集合
3 /// </summary>
4 /// <param name="provider">數據提供加載驅動</param>
5 /// <param name="sqlString">sql語句</param>
6 /// <returns></returns>
7 public DataTable ExecuteTable(IDbProvider provider, string sqlString)
8 {
9 return ExecuteTable(provider, sqlString, false, null);
10 }
11
12 /// <summary>
13 /// 獲得數據表結構集合
14 /// </summary>
15 /// <param name="provider">數據提供加載驅動</param>
16 /// <param name="sqlString">sql語句</param>
17 /// <param name="isProcedure">是否為存儲過程</param>
18 /// <returns></returns>
19 public DataTable ExecuteTable(IDbProvider provider, string sqlString, bool isProcedure)
20 {
21 return ExecuteTable(provider, sqlString, isProcedure, null);
22 }
23
24 /// <summary>
25 /// 獲得數據表結構集合
26 /// </summary>
27 /// <param name="provider">數據提供加載驅動</param>
28 /// <param name="sqlString">sql語句</param>
29 /// <param name="param">sql語句對應參數</param>
30 /// <returns></returns>
31 public DataTable ExecuteTable(IDbProvider provider, string sqlString, params IDataParameter[] param)
32 {
33 return ExecuteTable(provider, sqlString, false, param);
34 }
35
36 /// <summary>
37 /// 獲得數據表結構集合
38 /// </summary>
39 /// <param name="provider">數據提供加載驅動</param>
40 /// <param name="sqlString">sql語句</param>
41 /// <param name="isProcedure">是否為存儲過程</param>
42 /// <param name="param">sql語句對應參數</param>
43 /// <returns></returns>
44 public DataTable ExecuteTable(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param)
45 {
46 provider.Connection.Open();
47 provider.Command.CommandText = sqlString;
48 if (isProcedure)
49 {
50 provider.Command.CommandType = CommandType.StoredProcedure;
51 }
52 else
53 {
54 provider.Command.CommandType = CommandType.Text;
55 }
56 provider.Command.Parameters.Clear();
57 provider.Command.Parameters.AddRange(param);
58 DataSet ds = new DataSet();
59 provider.Adapter.Fill(ds);
60 return ds.Tables[0];
61 }
5. IdataReader 轉換集合
上面提到了,這個ORM映射框架可以查詢返回Ilist<T>,程序開發過程中我們往往喜歡使用List 結合,特別是泛型集合。上面的數據庫操作其中一種返回的是IdataReader,于是我們就想使用IdataReader 轉換為List集合,或者List<T>泛型集合。但是這里遇到了一個問題,如果轉換為List<T> 泛型集合,我們如果給泛型類型賦值,在這個數據庫的操作過程中是進行了高度的抽象的,我們是無法知道操作的具體類型,因此我們想到的是使用反射機制,在前面提到過的實體分析器,我們使用實體分析器分析了實體的詳細信息,并緩存在內存中。因此我們有了這個信息就可以很好的和數據庫對應起來。這個轉換的核心工作就是反射賦值,下面看看實現方式:
IdataReader 轉換為 T 泛型實體類:

2 /// 根據一個泛型類型獲得實體對象
3 /// </summary>
4 /// <typeparam name="T">泛型類型</typeparam>
5 /// <param name="reader">只讀數據流</param>
6 /// <returns></returns>
7 public T ConvertToEntity<T>(IDataReader reader) where T:class
8 {
9 T entity = default(T);
10 object result=ConvertToEntity(typeof(T),reader);
11 if (result != null)
12 {
13 entity=(T)result;
14 }
15 return entity;
16 }
17
18 /// <summary>
19 /// 將數據流裝化為對象
20 /// </summary>
21 /// <param name="type">轉化的目標類型</param>
22 /// <param name="reader">只讀數據流</param>
23 /// <returns></returns>
24 public object ConvertToEntity(Type type, IDataReader reader)
25 {
26 object entity = null;
27 if (reader.Read())
28 {
29 entity = EntityFactory.CreateInstance(type);
30 foreach (string key in EntityTypeCache.GetTableInfo(type).DicColumns.Keys)
31 {
32 if (string.IsNullOrEmpty(reader[key].ToString()))
33 {
34 EntityTypeCache.GetTableInfo(type).DicProperties[key].SetValue(entity, "", null);
35 }
36 else
37 {
38 EntityTypeCache.GetTableInfo(type).DicProperties[key].SetValue(entity, reader[key], null);
39 }
40 }
41 if (EntityTypeCache.GetTableInfo(type).DicLinkTable.Keys.Count > 0)
42 {
43 foreach (string key in EntityTypeCache.GetTableInfo(type).DicLinkTable.Keys)
44 {
45 Type entityType = EntityTypeCache.GetTableInfo(type).DicLinkTable[key].DataType;
46 string sql = Factory.CreateSingleSql(entityType);
47 IDataParameter[] param = new IDataParameter[]{
48 new SqlParameter()
49 };
50 param[0].ParameterName = "@" + EntityTypeCache.GetTableInfo(EntityTypeCache.GetTableInfo(type).DicLinkTable[key].DataType).Table.PrimaryKeyName;
51 param[0].Value = EntityFactory.GetPropertyValue(entity, EntityTypeCache.GetTableInfo(type).DicLinkTable[key].KeyName);
52 using (IDbProvider provider = new SqlProvider())
53 {
54 IDataReader read = ExecuteDataReader(provider, sql, param);
55 object entityChild = EntityFactory.CreateInstance(entityType, false);
56 if (read.Read())
57 {
58 foreach (string propertyName in EntityTypeCache.GetTableInfo(entityType).DicProperties.Keys)
59 {
60 EntityTypeCache.GetTableInfo(entityType).DicProperties[propertyName].SetValue(entityChild, read[EntityTypeCache.GetTableInfo(entityType).DicColumns[propertyName].Name], null);
61 }
62 }
63 EntityTypeCache.GetTableInfo(type).DicProperties[key].SetValue(entity, entityChild, null);
64 }
65 }
66 }
67 }
68 return entity;
69 }
IdataReader 轉換為Ilist<T> 泛型集合:

2 /// 根據一個泛型類型查詢一個集合
3 /// </summary>
4 /// <typeparam name="T">泛型類型</typeparam>
5 /// <param name="reader">只讀數據流</param>
6 /// <returns></returns>
7 public IList<T> ConvertToList<T>(IDataReader reader) where T : class
8 {
9 T entity = default(T);
10 IList<T> list = new List<T>();
11 while (reader.Read())
12 {
13 entity = EntityFactory.CreateInstance<T>();
14
15 foreach (string key in EntityTypeCache.GetTableInfo(typeof(T)).DicColumns.Keys)
16 {
17 if (string.IsNullOrEmpty(reader[key].ToString()))
18 {
19 EntityTypeCache.GetTableInfo(typeof(T)).DicProperties[key].SetValue(entity, null, null);
20 }
21 else
22 {
23 EntityTypeCache.GetTableInfo(typeof(T)).DicProperties[key].SetValue(entity, reader[key], null);
24 }
25 }
26 if (EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable.Keys.Count > 0)
27 {
28 foreach (string key in EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable.Keys)
29 {
30 Type entityType = EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable[key].DataType;
31 string sql = Factory.CreateSingleSql(entityType);
32 IDataParameter[] param = new IDataParameter[]{
33 new SqlParameter()
34 };
35 param[0].ParameterName = "@" + EntityTypeCache.GetTableInfo(EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable[key].DataType).Table.PrimaryKeyName;
36 param[0].Value = EntityFactory.GetPropertyValue(entity, EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable[key].KeyName);
37 using (IDbProvider provider = new SqlProvider())
38 {
39 IDataReader read = ExecuteDataReader(provider, sql, param);
40 object entityChild = EntityFactory.CreateInstance(entityType, false);
41 if (read.Read())
42 {
43 foreach (string propertyName in EntityTypeCache.GetTableInfo(entityType).DicProperties.Keys)
44 {
45 EntityTypeCache.GetTableInfo(entityType).DicProperties[propertyName].SetValue(entityChild, read[EntityTypeCache.GetTableInfo(entityType).DicColumns[propertyName].Name], null);
46 }
47 }
48 EntityTypeCache.GetTableInfo(typeof(T)).DicProperties[key].SetValue(entity, entityChild, null);
49 }
50 }
51 }
52 list.Add(entity);
53 }
54 return list;
55 }
對于T 和 Ilist<T> 的轉換其實是一樣的過程。在這個轉換的過程中有幾個值得注意的地方。
T entity = default(T);
default(T) 就好像我們實體對象賦初始值一樣,在泛型中因為類型的不確定,所以語法規定了以這種方式賦初始值。
entity = EntityFactory.CreateInstance<T>(); 而這據代碼是根據泛型類型創建了一個泛型實例,并在內存中分配空間。在這個里面定義了一個類,里面有很多方法,根據不同的情況,在動態創建對象,下面看看這個類的源碼,感覺在對象抽象到一定程序的時候,這種動態創建對象的方式就非常有必要了。

2 * 2010-1-28
3 *
4 * 情 緣
5 *
6 * 該實體類主要是通過反射機制來獲取泛型實體類的實例的
7 *
8 *
9 * */
10
11 using System;
12 using System.Reflection;
13
14
15 namespace CommonData.Entity
16 {
17 public static class EntityFactory
18 {
19 /// <summary>
20 /// 根據泛型類獲取該泛型類的實例,
21 /// T 泛型必須是class 類
22 /// </summary>
23 /// <typeparam name="T">泛型類</typeparam>
24 /// <returns></returns>
25 public static T CreateInstance<T>() where T :class
26 {
27 Type type = typeof(T);
28 Object result;
29 result = Activator.CreateInstance<T>();
30 return (T)result;
31 }
32
33 /// <summary>
34 /// 根據實體類型來創建實體實例
35 /// </summary>
36 /// <param name="type">要創建的對象的類型</param>
37 /// <param name="nonPublic">如果有顯示構造方法為true,如果沒有顯示構造方法為false</param>
38 /// <returns></returns>
39 public static object CreateInstance(Type type,bool nonPublic)
40 {
41 return Activator.CreateInstance(type,nonPublic);
42 }
43
44 /// <summary>
45 /// 根據實體類型和相關參數構造實體實例
46 /// </summary>
47 /// <param name="type">要創建的對象的類型</param>
48 /// <param name="param">與要調用構造函數的參數數量、順序和類型匹配的參數數組。如果 param 為空數組,則調用不帶任何參數的構造函數</param>
49 /// <returns></returns>
50 public static object CreateInstance(Type type,params object[] param)
51 {
52 return Activator.CreateInstance(type,param);
53 }
54
55 /// <summary>
56 /// 根據實體公共接口獲得特定屬性名稱的值
57 /// </summary>
58 /// <param name="entity">實體公共接口</param>
59 /// <param name="name">實體屬性名稱</param>
60 /// <returns></returns>
61 public static object GetPropertyValue(IEntity entity, string name)
62 {
63 PropertyInfo property = entity.GetType().GetProperty(name);
64 object result = null;
65 if (property != null)
66 {
67 result = property.GetValue(entity, null);
68 }
69 return result;
70 }
71
72 /// <summary>
73 /// 根據實體公共接口獲得特定屬性名稱的值,這個屬性是一個類
74 /// </summary>
75 /// <typeparam name="T">返回屬性的泛型類型</typeparam>
76 /// <param name="entity">實體公共接口</param>
77 /// <param name="name">實體屬性名稱</param>
78 /// <returns></returns>
79 public static T GetPropertyValue<T>(IEntity entity, string name) where T:class
80 {
81 object result = GetPropertyValue(entity, name);
82 if (result == null)
83 {
84 return default(T);
85 }
86 else
87 {
88 return (T)result;
89 }
90 }
91
92 /// <summary>
93 /// 獲得實體屬性值
94 /// </summary>
95 /// <param name="entity">實體類</param>
96 /// <param name="name">屬性名稱</param>
97 /// <returns></returns>
98 public static object GetPropertyValue(object entity, string name)
99 {
100 PropertyInfo property = entity.GetType().GetProperty(name);
101 object result = null;
102 if (property != null)
103 {
104 result = property.GetValue(entity, null);
105 }
106 return result;
107 }
108
109 /// <summary>
110 /// 根據實體公共接口設置某屬性的值
111 /// </summary>
112 /// <param name="entity">實體公共接口</param>
113 /// <param name="name">實體屬性名稱</param>
114 /// <param name="value">實體屬性值</param>
115 public static void SetPropertyValue(IEntity entity, string name, object value)
116 {
117 PropertyInfo property = entity.GetType().GetProperty(name);
118 if (property != null)
119 {
120 property.SetValue(name,value,null);
121 }
122 }
123
124 /// <summary>
125 /// 將某個值轉化為特定的類型
126 /// </summary>
127 /// <param name="type">轉化為的目標類型</param>
128 /// <param name="value">被轉化的值</param>
129 /// <returns></returns>
130 public static object ConvertValue(Type type, object value)
131 {
132 if (value == DBNull.Value)
133 {
134 return null;
135 }
136 return Convert.ChangeType(value,type);
137 }
138
139 /// <summary>
140 /// 將某個值轉化為特定的泛型類型
141 /// </summary>
142 /// <typeparam name="T">泛型類型</typeparam>
143 /// <param name="type">轉化為的目標類型</param>
144 /// <param name="value">被轉化的值</param>
145 /// <returns></returns>
146 public static T ConvertValue<T>(Type type, object value)
147 {
148 if (value == DBNull.Value)
149 {
150 return default(T);
151 }
152 return (T)Convert.ChangeType(value, type);
153 }
154 }
155 }
156
封裝集合其實就是根據實體分析緩存的信息,查找對應的數據流中的數據,動態的給對象賦值。在這個動態賦值的過程中有個地方,特別應該注意:
if (string.IsNullOrEmpty(reader[key].ToString()))
這句話就是講讀取的數據轉換為字符串,在之前也提到過,.NET 中的數據類型和SQL Server 中的數據類型是不同的,如果reader[key] 的值為null,如果我上面的這句判斷改為
If(reader[key]==null) 那么這里就會存在一個潛在的bug,上面已經說過了,數據庫中的類型和.NET 中的類型是不一樣的,需要使用DbNull 這個對象。更多類容不再多少,可以到網上查看更多的資料。
這個里面還有一個特殊的過程,那就是級聯查詢,當然這里只是做了級聯查詢父類的操作,至于級聯查詢子類集合的過程沒有做處理,這個在后期的改版中做修改。
6. 下面舉個小小的應用例子
沒時間了,簡單的介紹一下吧,不做詳細的講解了,后續在講解。
在這個ORM框架中還定義了一個接口,源碼如下:

2 * 2010-2-26
3 *
4 * 情 緣
5 *
6 * 該接口定了實體增刪改查的操作。
7 * 接口中的定義都是使用實體的公共
8 * 接口和泛型類型,這樣確保了方法
9 * 的公用性
10 *
11 * */
12 using System;
13 using System.Collections.Generic;
14 using System.Linq;
15 using System.Text;
16 using CommonData.Entity;
17 using CommonData.Model.Core;
18
19 namespace CommonData.Data.Core
20 {
21 public interface IDbHelper:IDisposable
22 {
23 /// <summary>
24 /// 添加實體對象
25 /// 將實體數據信息映射為一條插入sql語句
26 /// </summary>
27 /// <param name="entity">實體公共接口</param>
28 /// <returns></returns>
29 int Add(IEntity entity);
30
31 /// <summary>
32 /// 添加實體對象
33 /// 將泛型數據信息映射為一條插入sql語句
34 /// 該泛型類必須實現IEntity 接口
35 /// </summary>
36 /// <typeparam name="T">實體泛型類型</typeparam>
37 /// <param name="t">泛型實體值</param>
38 /// <returns></returns>
39 int Add<T>(T t) where T : IEntity;
40
41 /// <summary>
42 /// 添加實體對象
43 /// value 的類型必須和type一致,這樣才能保存值
44 /// </summary>
45 /// <param name="type">實體類型</param>
46 /// <param name="value">實體類型實例</param>
47 /// <returns></returns>
48 int Add(Type type, object value);
49
50 /// <summary>
51 /// 根據實體公共接口修改該實體信息
52 /// 該實體是根據主鍵修改
53 /// </summary>
54 /// <param name="entity">實體公共接口</param>
55 /// <returns></returns>
56 int Update(IEntity entity);
57
58 /// <summary>
59 /// 根據實體的某個屬性修改數據
60 /// entity 中必須包含該屬性,而且該屬性的
61 /// 值不能為空
62 /// </summary>
63 /// <param name="entity">實體公共接口</param>
64 /// <param name="propertyName">實體屬性名稱</param>
65 /// <returns></returns>
66 int Update(IEntity entity,string propertyName);
67
68 /// <summary>
69 /// 根據實體的多個屬性修改數據
70 /// 數組中的屬性名稱必須存在.
71 /// 傳遞參數數組不能為null
72 /// </summary>
73 /// <param name="entity">實體公共接口</param>
74 /// <param name="propertyNames">屬性名稱數組</param>
75 /// <returns></returns>
76 int Update(IEntity entity,string[] propertyNames);
77
78 /// <summary>
79 /// 修改實體信息
80 /// 該實體是根據主鍵修改
81 /// </summary>
82 /// <typeparam name="T">實體泛型類型</typeparam>
83 /// <param name="t">泛型實例</param>
84 /// <returns></returns>
85 int Update<T>(T t) where T : IEntity;
86
87 /// <summary>
88 /// 根據泛型類的某個實體屬性來修改該數據。
89 /// 泛型實體實例中該屬性不能為空
90 /// </summary>
91 /// <typeparam name="T">泛型類</typeparam>
92 /// <param name="t">泛型實例</param>
93 /// <param name="propertyName"></param>
94 /// <returns></returns>
95 int Update<T>(T t, string propertyName) where T : IEntity;
96
97 /// <summary>
98 /// 根據實體的多個屬性修改數據
99 /// 數組中的屬性名稱在泛型類中必須存在,
100 /// 數組不能傳遞null值
101 /// </summary>
102 /// <typeparam name="T">泛型類</typeparam>
103 /// <param name="t">泛型實例</param>
104 /// <param name="propertyNames">屬性名稱數組</param>
105 /// <returns></returns>
106 int Update<T>(T t, string[] propertyNames) where T : IEntity;
107
108 /// <summary>
109 /// 修改實體信息
110 /// 該實體是根據主鍵修改
111 /// </summary>
112 /// <param name="type">實體類型</param>
113 /// <param name="value">實體對象實例</param>
114 /// <returns></returns>
115 int Update(Type type, object value);
116
117 /// <summary>
118 /// 根據實體的某個屬性來修改數據信息
119 /// 該方法使用Type 來確定需要修改的實體對象
120 /// value 實例中必須包含propertyName 這個屬性
121 /// 而且propertyName 屬性值不能為空
122 /// </summary>
123 /// <param name="type">實體類型</param>
124 /// <param name="value">實體實例</param>
125 /// <param name="propertyName">屬性名稱</param>
126 /// <returns></returns>
127 int Update(Type type, object value, string propertyName);
128
129 /// <summary>
130 /// 根據實體的多個屬性來修改數據信息
131 /// 該方法使用Type 來確定需要修改的實體對象
132 /// 數組中的屬性名稱在泛型類中必須存在,
133 /// 而且數組傳遞參數不能為null
134 /// </summary>
135 /// <param name="type">實體類型</param>
136 /// <param name="value">實體實例</param>
137 /// <param name="propertyNames">屬性名稱數組</param>
138 /// <returns></returns>
139 int Update(Type type,object value,string[] propertyNames);
140
141 /// <summary>
142 /// 刪除實體對象
143 /// 該方法是根據實體對象主鍵刪除數據
144 /// </summary>
145 /// <param name="entity">實體公共接口</param>
146 /// <returns></returns>
147 int Delete(IEntity entity);
148
149 /// <summary>
150 /// 根據某個實體屬性刪除數據
151 /// 該實體必須包含指定的屬性名稱
152 /// 而且實體屬性值不能為空
153 /// </summary>
154 /// <param name="entity">實體屬性公共接口</param>
155 /// <param name="propertyName">實體屬性名稱</param>
156 /// <returns></returns>
157 int Delete(IEntity entity, string propertyName);
158
159 /// <summary>
160 /// 根據實體多個屬性刪除數據
161 /// 實體中必須包含該屬性
162 /// 傳遞參數數組不能為空
163 /// </summary>
164 /// <param name="entity">實體屬性公共接口</param>
165 /// <param name="propertyNames">實體屬性名稱數組</param>
166 /// <returns></returns>
167 int Delete(IEntity entity,string[] propertyNames);
168
169 /// <summary>
170 /// 根據泛型類刪除數據
171 /// 該方法是根據實體的主鍵刪除的
172 /// </summary>
173 /// <typeparam name="T">泛型類</typeparam>
174 /// <param name="t">泛型實例</param>
175 /// <returns></returns>
176 int Delete<T>(T t) where T : class;
177
178 /// <summary>
179 /// 根據泛型類的某個屬性刪除數據
180 /// 泛型類中必須存在該屬性,而且
181 /// 屬性值不能為空
182 /// </summary>
183 /// <typeparam name="T">泛型類型</typeparam>
184 /// <param name="t">泛型類實例</param>
185 /// <param name="propertyName">屬性名稱</param>
186 /// <returns></returns>
187 int Delete<T>(T t, string propertyName) where T : class;
188
189 /// <summary>
190 /// 根據泛型類型的多個屬性刪除數據
191 /// 泛型類型中必須存在這些屬性,傳
192 /// 遞參數的時候不能為null
193 /// </summary>
194 /// <typeparam name="T">泛型類</typeparam>
195 /// <param name="t">泛型實例</param>
196 /// <param name="propertyNames">屬性名稱數組</param>
197 /// <returns></returns>
198 int Delete<T>(T t, string[] propertyNames) where T : class;
199
200 /// <summary>
201 /// 根據實體的類型刪除數據。
202 /// value 中的類型由type確定
203 /// </summary>
204 /// <param name="type">實體類型</param>
205 /// <param name="value">實體對象實例</param>
206 /// <returns></returns>
207 int Delete(Type type, object value);
208
209 /// <summary>
210 /// 根據實體的類型的某個屬性刪除數據。
211 /// value 中的類型由type確定
212 /// propertyName 屬性名稱必須在value
213 /// 對象中存在
214 /// </summary>
215 /// <param name="type">實體類型</param>
216 /// <param name="value">實體對象實例</param>
217 /// <param name="propertyName">屬性名稱</param>
218 /// <returns></returns>
219 int Delete(Type type,object value,string propertyName);
220
221 /// <summary>
222 /// 根據實體的類型的某個屬性刪除數據。
223 /// value 中的類型由type確定
224 /// propertyName 屬性名稱必須在value
225 /// 對象中存在
226 /// </summary>
227 /// <param name="type">實體類型</param>
228 /// <param name="value">實體對象實例</param>
229 /// <param name="propertyNames">屬性名稱數組</param>
230 /// <returns></returns>
231 int Delete(Type type,object value,string[] propertyNames);
232
233 /// <summary>
234 /// 根據主鍵查詢實體對象
235 /// </summary>
236 /// <typeparam name="T">泛型類型</typeparam>
237 /// <param name="pkPropertyValue">主鍵值</param>
238 /// <returns></returns>
239 T GetEntity<T>(object pkPropertyValue) where T : class;
240
241 /// <summary>
242 /// 根據實體類的類型和主鍵值查詢實體對象
243 /// 使用 type 確定實體,主鍵確定數據的唯
244 /// 一性
245 /// </summary>
246 /// <param name="type">實體類型</param>
247 /// <param name="pkPropertyValue">主鍵值</param>
248 /// <returns></returns>
249 object GetEntity(Type type, object pkPropertyValue);
250
251 /// <summary>
252 /// 根據某個實體的屬性來查詢實體對象
253 /// 該屬性值能確定數據庫唯一數據行
254 /// </summary>
255 /// <typeparam name="T">實體泛型類</typeparam>
256 /// <param name="propertyName">屬性名稱</param>
257 /// <param name="propertyValue">屬性值</param>
258 /// <returns></returns>
259 T GetEntity<T>(string propertyName, object propertyValue) where T : class;
260
261 /// <summary>
262 /// 根據某個實體的屬性來查詢實體對象
263 /// 該屬性值能確定數據庫唯一數據行
264 /// </summary>
265 /// <param name="type">實體類型</param>
266 /// <param name="propertyName">屬性名稱</param>
267 /// <param name="propertyValue">屬性值</param>
268 /// <returns></returns>
269 object GetEntity(Type type, string propertyName, object propertyValue);
270
271 /// <summary>
272 /// 根據某個實體的多個屬性來查詢實體對象
273 /// </summary>
274 /// <typeparam name="T">泛型類</typeparam>
275 /// <param name="entity">實體公共接口</param>
276 /// <param name="propertyNames">屬性名稱數組</param>
277 /// <returns></returns>
278 T GetEntity<T>(IEntity entity, string[] propertyNames) where T : class;
279
280 /// <summary>
281 /// 根據某個實體的多個屬性來查詢實體對象
282 /// 實體根據type類型來確定
283 /// </summary>
284 /// <param name="type">實體類型</param>
285 /// <param name="entity">實體公共接口</param>
286 /// <param name="propertyNames">屬性名稱數組</param>
287 /// <returns></returns>
288 object GetEntity(Type type, IEntity entity, string[] propertyNames);
289
290 /// <summary>
291 /// 查詢該類型實體數據行數
292 /// </summary>
293 /// <param name="type">實體類型</param>
294 /// <returns></returns>
295 int GetCount(Type type);
296
297 /// <summary>
298 /// 查詢該類型實體數據行數
299 /// </summary>
300 /// <typeparam name="T">泛型類型</typeparam>
301 /// <returns></returns>
302 int GetCount<T>() where T : class;
303
304 /// <summary>
305 /// 根據條件查詢實體數據行數
306 /// </summary>
307 /// <param name="type">實體類型</param>
308 /// <param name="dic">實體屬性鍵值對</param>
309 /// <param name="component">查詢組件</param>
310 /// <returns></returns>
311 int GetCount(Type type, IDictionary<string, object> dic, ConditionComponent component);
312
313 /// <summary>
314 /// 查詢所有實體集合
315 /// </summary>
316 /// <typeparam name="T">泛型類型</typeparam>
317 /// <returns></returns>
318 IList<T> GetList<T>() where T : class;
319
320 /// <summary>
321 /// 根據某個實體屬性查詢實體集合
322 /// </summary>
323 /// <typeparam name="T">泛型類型</typeparam>
324 /// <param name="propertyName">屬性名稱</param>
325 /// <param name="value">屬性值</param>
326 /// <returns></returns>
327 IList<T> GetList<T>(string propertyName, object value) where T : class;
328
329 /// <summary>
330 /// 根據多個屬性查詢實體集合
331 /// </summary>
332 /// <typeparam name="T">泛型類型</typeparam>
333 /// <param name="entity">實體公共接口</param>
334 /// <param name="propertyNames">屬性名稱</param>
335 /// <returns></returns>
336 IList<T> GetList<T>(IDictionary<string, object> dic) where T : class;
337
338 /// <summary>
339 /// 根據多個屬性查詢實體集合
340 /// 該查詢方式附加查詢組建
341 /// </summary>
342 /// <typeparam name="T">類型類</typeparam>
343 /// <param name="dic">屬性鍵值對</param>
344 /// <param name="component">查詢組件</param>
345 /// <returns></returns>
346 IList<T> GetList<T>(IDictionary<string, object> dic, ConditionComponent component) where T : class;
347 }
348 }
349
上面的接口實現類:

2 * 2010-2-26
3 *
4 * 情 緣
5 *
6 * 當前類實現了IDbHelper接口,主要用于對實體進行
7 * 增刪改查操作。
8 *
9 * */
10 using System;
11 using System.Collections.Generic;
12 using System.Linq;
13 using System.Text;
14 using CommonData.Entity;
15 using System.Data;
16 using CommonData.Model.Core;
17
18 namespace CommonData.Data.Core.SQLCore
19 {
20 public class SqlHelper:IDbHelper
21 {
22 private IBaseHelper baseHelper;
23 /// <summary>
24 /// 數據庫操作公共接口
25 /// </summary>
26 public IBaseHelper BaseHelper
27 {
28 get
29 {
30 if (baseHelper == null)
31 {
32 baseHelper = new BaseHelper();
33 }
34 return baseHelper;
35 }
36 set
37 {
38 baseHelper = value;
39 }
40 }
41
42 private IDbFactory factory;
43 /// <summary>
44 /// sql語句構造工廠對象
45 /// </summary>
46 public IDbFactory Factory
47 {
48 get
49 {
50 if (factory == null)
51 {
52 factory = new SqlFactory();
53 }
54 return factory;
55 }
56 set
57 {
58 factory = value;
59 }
60 }
61
62
63 /// <summary>
64 /// 添加實體對象
65 /// 將實體數據信息映射為一條插入sql語句
66 /// </summary>
67 /// <param name="entity">實體公共接口</param>
68 /// <returns></returns>
69 public int Add(IEntity entity)
70 {
71 IDataParameter[] param = null;
72 string sql = Factory.CreateInsertSql(entity,out param);
73 using(IDbProvider provider=new SqlProvider())
74 {
75 return BaseHelper.ExecuteNonQuery(provider,sql,param);
76 }
77 }
78
79 /// <summary>
80 /// 添加實體對象
81 /// 將泛型數據信息映射為一條插入sql語句
82 /// 該泛型類必須實現IEntity 接口
83 /// </summary>
84 /// <typeparam name="T">實體泛型類型</typeparam>
85 /// <param name="t">泛型實體值</param>
86 /// <returns></returns>
87 public int Add<T>(T t) where T : IEntity
88 {
89 IDataParameter[] param = null;
90 string sql = Factory.CreateInsertSql<T>(t,out param);
91 using (IDbProvider provider = new SqlProvider())
92 {
93 return BaseHelper.ExecuteNonQuery(provider, sql, param);
94 }
95 }
96
97 /// <summary>
98 /// 添加實體對象
99 /// value 的類型必須和type一致,這樣才能保存值
100 /// </summary>
101 /// <param name="type">實體類型</param>
102 /// <param name="value">實體類型實例</param>
103 /// <returns></returns>
104 public int Add(Type type, object value)
105 {
106 IDataParameter[] param = null;
107 string sql = Factory.CreateInsertSql(type,value,out param);
108 using (IDbProvider provider = new SqlProvider())
109 {
110 return BaseHelper.ExecuteNonQuery(provider, sql, param);
111 }
112 }
113
114 /// <summary>
115 /// 根據實體公共接口修改該實體信息
116 /// 該實體是根據主鍵修改
117 /// </summary>
118 /// <param name="entity">實體公共接口</param>
119 /// <returns></returns>
120 public int Update(IEntity entity)
121 {
122 IDataParameter[] param = null;
123 string sql = Factory.CreateUpdateSql(entity,out param);
124 using (IDbProvider provider = new SqlProvider())
125 {
126 return BaseHelper.ExecuteNonQuery(provider, sql, param);
127 }
128 }
129
130 /// <summary>
131 /// 根據實體的某個屬性修改數據
132 /// entity 中必須包含該屬性,而且該屬性的
133 /// 值不能為空
134 /// </summary>
135 /// <param name="entity">實體公共接口</param>
136 /// <param name="propertyName">實體屬性名稱</param>
137 /// <returns></returns>
138 public int Update(IEntity entity, string propertyName)
139 {
140 IDataParameter[] param = null;
141 string sql = Factory.CreateUpdateSql(entity, out param, propertyName);
142 using (IDbProvider provider = new SqlProvider())
143 {
144 return BaseHelper.ExecuteNonQuery(provider, sql, param);
145 }
146 }
147
148 /// <summary>
149 /// 根據實體的多個屬性修改數據
150 /// 數組中的屬性名稱必須存在.
151 /// 傳遞參數數組不能為null
152 /// </summary>
153 /// <param name="entity">實體公共接口</param>
154 /// <param name="propertyNames">屬性名稱數組</param>
155 /// <returns></returns>
156 public int Update(IEntity entity, string[] propertyNames)
157 {
158 IDataParameter[] param = null;
159 string sql = Factory.CreateUpdateSql(entity,out param,propertyNames);
160 using (IDbProvider provider = new SqlProvider())
161 {
162 return BaseHelper.ExecuteNonQuery(provider, sql, param);
163 }
164 }
165
166 /// <summary>
167 /// 修改實體信息
168 /// 該實體是根據主鍵修改
169 /// </summary>
170 /// <typeparam name="T">實體泛型類型</typeparam>
171 /// <param name="t">泛型實例</param>
172 /// <returns></returns>
173 public int Update<T>(T t) where T : IEntity
174 {
175 IDataParameter[] param = null;
176 string sql = Factory.CreateUpdateSql(typeof(T),t,out param);
177 using (IDbProvider provider = new SqlProvider())
178 {
179 return BaseHelper.ExecuteNonQuery(provider, sql, param);
180 }
181 }
182
183 /// <summary>
184 /// 根據泛型類的某個實體屬性來修改該數據。
185 /// 泛型實體實例中該屬性不能為空
186 /// </summary>
187 /// <typeparam name="T">泛型類</typeparam>
188 /// <param name="t">泛型實例</param>
189 /// <param name="propertyName"></param>
190 /// <returns></returns>
191 public int Update<T>(T t, string propertyName) where T : IEntity
192 {
193 IDataParameter[] param = null;
194 string sql = Factory.CreateUpdateSql(typeof(T), t, out param,propertyName);
195 using (IDbProvider provider = new SqlProvider())
196 {
197 return BaseHelper.ExecuteNonQuery(provider, sql, param);
198 }
199 }
200
201 /// <summary>
202 /// 根據實體的多個屬性修改數據
203 /// 數組中的屬性名稱在泛型類中必須存在,
204 /// 數組不能傳遞null值
205 /// </summary>
206 /// <typeparam name="T">泛型類</typeparam>
207 /// <param name="t">泛型實例</param>
208 /// <param name="propertyNames">屬性名稱數組</param>
209 /// <returns></returns>
210 public int Update<T>(T t, string[] propertyNames) where T : IEntity
211 {
212 IDataParameter[] param = null;
213 string sql = Factory.CreateUpdateSql(typeof(T), t, out param, propertyNames);
214 using (IDbProvider provider = new SqlProvider())
215 {
216 return BaseHelper.ExecuteNonQuery(provider, sql, param);
217 }
218 }
219
220 /// <summary>
221 /// 修改實體信息
222 /// 該實體是根據主鍵修改
223 /// </summary>
224 /// <param name="type">實體類型</param>
225 /// <param name="value">實體對象實例</param>
226 /// <returns></returns>
227 public int Update(Type type, object value)
228 {
229 IDataParameter[] param = null;
230 string sql = Factory.CreateUpdateSql(type,value,out param);
231 using (IDbProvider provider = new SqlProvider())
232 {
233 return BaseHelper.ExecuteNonQuery(provider, sql, param);
234 }
235 }
236
237 /// <summary>
238 /// 根據實體的某個屬性來修改數據信息
239 /// 該方法使用Type 來確定需要修改的實體對象
240 /// value 實例中必須包含propertyName 這個屬性
241 /// 而且propertyName 屬性值不能為空
242 /// </summary>
243 /// <param name="type">實體類型</param>
244 /// <param name="value">實體實例</param>
245 /// <param name="propertyName">屬性名稱</param>
246 /// <returns></returns>
247 public int Update(Type type, object value, string propertyName)
248 {
249 IDataParameter[] param = null;
250 string sql = Factory.CreateUpdateSql(type, value, out param, propertyName);
251 using (IDbProvider provider = new SqlProvider())
252 {
253 return BaseHelper.ExecuteNonQuery(provider, sql, param);
254 }
255 }
256
257 /// <summary>
258 /// 根據實體的多個屬性來修改數據信息
259 /// 該方法使用Type 來確定需要修改的實體對象
260 /// 數組中的屬性名稱在泛型類中必須存在,
261 /// 而且數組傳遞參數不能為null
262 /// </summary>
263 /// <param name="type">實體類型</param>
264 /// <param name="value">實體實例</param>
265 /// <param name="propertyNames">屬性名稱數組</param>
266 /// <returns></returns>
267 public int Update(Type type, object value, string[] propertyNames)
268 {
269 IDataParameter[] param = null;
270 string sql = Factory.CreateUpdateSql(type, value, out param, propertyNames);
271 using (IDbProvider provider = new SqlProvider())
272 {
273 return BaseHelper.ExecuteNonQuery(provider, sql, param);
274 }
275 }
276
277
278
279
280 /// <summary>
281 /// 刪除實體對象
282 /// 該方法是根據實體對象主鍵刪除數據
283 /// </summary>
284 /// <param name="entity">實體公共接口</param>
285 /// <returns></returns>
286 public int Delete(IEntity entity)
287 {
288 IDataParameter[] param = null;
289 string sql = Factory.CreateDeleteSql(entity,out param);
290 using (IDbProvider provider = new SqlProvider())
291 {
292 return BaseHelper.ExecuteNonQuery(provider, sql, param);
293 }
294 }
295
296 /// <summary>
297 /// 根據某個實體屬性刪除數據
298 /// 該實體必須包含指定的屬性名稱
299 /// 而且實體屬性值不能為空
300 /// </summary>
301 /// <param name="entity">實體屬性公共接口</param>
302 /// <param name="propertyName">實體屬性名稱</param>
303 /// <returns></returns>
304 public int Delete(IEntity entity, string propertyName)
305 {
306 IDataParameter[] param = null;
307 string sql = Factory.CreateDeleteSql(entity,out param,propertyName);
308 using (IDbProvider provider = new SqlProvider())
309 {
310 return BaseHelper.ExecuteNonQuery(provider, sql, param);
311 }
312 }
313
314 /// <summary>
315 /// 根據實體多個屬性刪除數據
316 /// 實體中必須包含該屬性
317 /// 傳遞參數數組不能為空
318 /// </summary>
319 /// <param name="entity">實體屬性公共接口</param>
320 /// <param name="propertyNames">實體屬性名稱數組</param>
321 /// <returns></returns>
322 public int Delete(IEntity entity, string[] propertyNames)
323 {
324 IDataParameter[] param = null;
325 string sql = Factory.CreateDeleteSql(entity, out param, propertyNames);
326 using (IDbProvider provider = new SqlProvider())
327 {
328 return BaseHelper.ExecuteNonQuery(provider, sql, param);
329 }
330 }
331
332 /// <summary>
333 /// 根據泛型類刪除數據
334 /// 該方法是根據實體的主鍵刪除的
335 /// </summary>
336 /// <typeparam name="T">泛型類</typeparam>
337 /// <param name="t">泛型實例</param>
338 /// <returns></returns>
339 public int Delete<T>(T t) where T : class
340 {
341 IDataParameter[] param = null;
342 string sql = Factory.CreateDeleteSql(typeof(T), t, out param);
343 using (IDbProvider provider = new SqlProvider())
344 {
345 return BaseHelper.ExecuteNonQuery(provider, sql, param);
346 }
347 }
348
349 /// <summary>
350 /// 根據泛型類的某個屬性刪除數據
351 /// 泛型類中必須存在該屬性,而且
352 /// 屬性值不能為空
353 /// </summary>
354 /// <typeparam name="T">泛型類型</typeparam>
355 /// <param name="t">泛型類實例</param>
356 /// <param name="propertyName">屬性名稱</param>
357 /// <returns></returns>
358 public int Delete<T>(T t, string propertyName) where T : class
359 {
360 IDataParameter[] param = null;
361 string sql = Factory.CreateDeleteSql(typeof(T), t, out param,propertyName);
362 using (IDbProvider provider = new SqlProvider())
363 {
364 return BaseHelper.ExecuteNonQuery(provider, sql, param);
365 }
366 }
367
368 /// <summary>
369 /// 根據泛型類型的多個屬性刪除數據
370 /// 泛型類型中必須存在這些屬性,傳
371 /// 遞參數的時候不能為null
372 /// </summary>
373 /// <typeparam name="T">泛型類</typeparam>
374 /// <param name="t">泛型實例</param>
375 /// <param name="propertyNames">屬性名稱數組</param>
376 /// <returns></returns>
377 public int Delete<T>(T t, string[] propertyNames) where T : class
378 {
379 IDataParameter[] param = null;
380 string sql = Factory.CreateDeleteSql(typeof(T), t, out param, propertyNames);
381 using (IDbProvider provider = new SqlProvider())
382 {
383 return BaseHelper.ExecuteNonQuery(provider, sql, param);
384 }
385 }
386
387 /// <summary>
388 /// 根據實體的類型刪除數據。
389 /// value 中的類型由type確定
390 /// </summary>
391 /// <param name="type">實體類型</param>
392 /// <param name="value">實體對象實例</param>
393 /// <returns></returns>
394 public int Delete(Type type, object value)
395 {
396 IDataParameter[] param = null;
397 string sql = Factory.CreateDeleteSql(type,value,out param);
398 using (IDbProvider provider = new SqlProvider())
399 {
400 return BaseHelper.ExecuteNonQuery(provider, sql, param);
401 }
402 }
403
404 /// <summary>
405 /// 根據實體的類型的某個屬性刪除數據。
406 /// value 中的類型由type確定
407 /// propertyName 屬性名稱必須在value
408 /// 對象中存在
409 /// </summary>
410 /// <param name="type">實體類型</param>
411 /// <param name="value">實體對象實例</param>
412 /// <param name="propertyName">屬性名稱</param>
413 /// <returns></returns>
414 public int Delete(Type type, object value, string propertyName)
415 {
416 IDataParameter[] param = null;
417 string sql = Factory.CreateDeleteSql(type, value, out param,propertyName);
418 using (IDbProvider provider = new SqlProvider())
419 {
420 return BaseHelper.ExecuteNonQuery(provider, sql, param);
421 }
422 }
423
424 /// <summary>
425 /// 根據實體的類型的某個屬性刪除數據。
426 /// value 中的類型由type確定
427 /// propertyName 屬性名稱必須在value
428 /// 對象中存在
429 /// </summary>
430 /// <param name="type">實體類型</param>
431 /// <param name="value">實體對象實例</param>
432 /// <param name="propertyNames">屬性名稱數組</param>
433 /// <returns></returns>
434 public int Delete(Type type, object value, string[] propertyNames)
435 {
436 IDataParameter[] param = null;
437 string sql = Factory.CreateDeleteSql(type, value, out param, propertyNames);
438 using (IDbProvider provider = new SqlProvider())
439 {
440 return BaseHelper.ExecuteNonQuery(provider, sql, param);
441 }
442 }
443
444 /// <summary>
445 /// 根據主鍵查詢實體對象
446 /// </summary>
447 /// <typeparam name="T">泛型類型</typeparam>
448 /// <param name="pkPropertyValue">主鍵值</param>
449 /// <returns></returns>
450 public T GetEntity<T>(object pkPropertyValue) where T : class
451 {
452 IDataParameter[] param = null;
453 string sql = Factory.CreateSingleSql(typeof(T), pkPropertyValue, out param);
454 using (IDbProvider provider = new SqlProvider())
455 {
456 return BaseHelper.ConvertToEntity<T>(BaseHelper.ExecuteDataReader(provider,sql,param));
457 }
458 }
459
460 /// <summary>
461 /// 根據實體類的類型和主鍵值查詢實體對象
462 /// 使用 type 確定實體,主鍵確定數據的唯
463 /// 一性
464 /// </summary>
465 /// <param name="type">實體類型</param>
466 /// <param name="pkPropertyValue">主鍵值</param>
467 /// <returns></returns>
468 public object GetEntity(Type type, object pkPropertyValue)
469 {
470 IDataParameter[] param = null;
471 string sql = Factory.CreateSingleSql(type,pkPropertyValue,out param);
472 using (IDbProvider provider = new SqlProvider())
473 {
474 return baseHelper.ConvertToEntity(type,BaseHelper.ExecuteDataReader(provider,sql,param));
475 }
476 }
477
478 /// <summary>
479 /// 根據某個實體的屬性來查詢實體對象
480 /// 該屬性值能確定數據庫唯一數據行
481 /// </summary>
482 /// <typeparam name="T">實體泛型類</typeparam>
483 /// <param name="propertyName">屬性名稱</param>
484 /// <param name="propertyValue">屬性值</param>
485 /// <returns></returns>
486 public T GetEntity<T>(string propertyName, object propertyValue) where T : class
487 {
488 IDataParameter[] param = null;
489 string sql = Factory.CreateQueryByPropertySql(typeof(T),propertyName,propertyValue,out param);
490 using (IDbProvider provider = new SqlProvider())
491 {
492 return BaseHelper.ConvertToEntity<T>(BaseHelper.ExecuteDataReader(provider,sql,param));
493 }
494 }
495
496 /// <summary>
497 /// 根據某個實體的屬性來查詢實體對象
498 /// 該屬性值能確定數據庫唯一數據行
499 /// </summary>
500 /// <param name="type">實體類型</param>
501 /// <param name="propertyName">屬性名稱</param>
502 /// <param name="propertyValue">屬性值</param>
503 /// <returns></returns>
504 public object GetEntity(Type type, string propertyName, object propertyValue)
505 {
506 IDataParameter[] param = null;
507 string sql = Factory.CreateQueryByPropertySql(type, propertyName, propertyValue, out param);
508 using (IDbProvider provider = new SqlProvider())
509 {
510 return BaseHelper.ConvertToEntity(type,BaseHelper.ExecuteDataReader(provider,sql,param));
511 }
512 }
513
514 /// <summary>
515 /// 根據某個實體的多個屬性來查詢實體對象
516 /// </summary>
517 /// <typeparam name="T">泛型類</typeparam>
518 /// <param name="entity">實體公共接口</param>
519 /// <param name="propertyNames">屬性名稱數組</param>
520 /// <returns></returns>
521 public T GetEntity<T>(IEntity entity, string[] propertyNames) where T : class
522 {
523 IDataParameter[] param = null;
524 string sql = Factory.CreateSingleSql(entity,out param,propertyNames);
525 using (IDbProvider provider = new SqlProvider())
526 {
527 return BaseHelper.ConvertToEntity<T>(BaseHelper.ExecuteDataReader(provider,sql,param));
528 }
529 }
530
531 /// <summary>
532 /// 根據某個實體的多個屬性來查詢實體對象
533 /// 實體根據type類型來確定
534 /// </summary>
535 /// <param name="type">實體類型</param>
536 /// <param name="entity">實體公共接口</param>
537 /// <param name="propertyNames">屬性名稱數組</param>
538 /// <returns></returns>
539 public object GetEntity(Type type, IEntity entity, string[] propertyNames)
540 {
541 IDataParameter[] param = null;
542 string sql = Factory.CreateSingleSql(type,entity,out param,propertyNames);
543 using (IDbProvider provider = new SqlProvider())
544 {
545 return BaseHelper.ConvertToEntity(type,BaseHelper.ExecuteDataReader(provider,sql,param));
546 }
547 }
548
549
550 /// <summary>
551 /// 查詢該類型實體數據行數
552 /// </summary>
553 /// <param name="type">實體類型</param>
554 /// <returns></returns>
555 public int GetCount(Type type)
556 {
557 string sql = Factory.CreateConverageSql(type,Converage.Count);
558 using (IDbProvider provider = new SqlProvider())
559 {
560 return (int)BaseHelper.ExecuteScalar(provider,sql);
561 }
562 }
563
564 /// <summary>
565 /// 查詢該類型實體數據行數
566 /// </summary>
567 /// <typeparam name="T">泛型類型</typeparam>
568 /// <returns></returns>
569 public int GetCount<T>() where T : class
570 {
571 string sql = Factory.CreateConverageSql(typeof(T), Converage.Count);
572 using (IDbProvider provider = new SqlProvider())
573 {
574 return (int)BaseHelper.ExecuteScalar(provider, sql);
575 }
576 }
577
578 /// <summary>
579 /// 根據條件查詢實體數據行數
580 /// </summary>
581 /// <param name="type">實體類型</param>
582 /// <param name="dic">實體屬性鍵值對</param>
583 /// <param name="component">查詢組件</param>
584 /// <returns></returns>
585 public int GetCount(Type type, IDictionary<string, object> dic, ConditionComponent component)
586 {
587 IDataParameter[] param = null;
588 string sql = Factory.CreateConverageSql(type,Converage.Count,"",dic,out param,component);
589 using (IDbProvider provider = new SqlProvider())
590 {
591 return (int)BaseHelper.ExecuteScalar(provider, sql, param);
592 }
593 }
594
595 /// <summary>
596 /// 查詢所有實體集合
597 /// </summary>
598 /// <typeparam name="T">泛型類型</typeparam>
599 /// <returns></returns>
600 public IList<T> GetList<T>() where T : class
601 {
602 string sql = Factory.CreateQuerySql(typeof(T));
603 using (IDbProvider provider = new SqlProvider())
604 {
605 return BaseHelper.ConvertToList<T>(BaseHelper.ExecuteDataReader(provider,sql));
606 }
607 }
608
609 /// <summary>
610 /// 根據某個實體屬性查詢實體集合
611 /// </summary>
612 /// <typeparam name="T">泛型類型</typeparam>
613 /// <param name="propertyName">屬性名稱</param>
614 /// <param name="value">屬性值</param>
615 /// <returns></returns>
616 public IList<T> GetList<T>(string propertyName, object value) where T : class
617 {
618 IDataParameter[] param = null;
619 string sql = Factory.CreateQueryByPropertySql(typeof(T),propertyName,value,out param);
620 using (IDbProvider provider = new SqlProvider())
621 {
622 return BaseHelper.ConvertToList<T>(BaseHelper.ExecuteDataReader(provider, sql,param));
623 }
624 }
625
626
627 /// <summary>
628 /// 根據多個屬性查詢實體集合
629 /// </summary>
630 /// <typeparam name="T">泛型類型</typeparam>
631 /// <param name="entity">實體公共接口</param>
632 /// <param name="propertyNames">屬性名稱</param>
633 /// <returns></returns>
634 public IList<T> GetList<T>(IDictionary<string,object> dic) where T : class
635 {
636 IDataParameter[] param = null;
637 string sql = Factory.CreateQueryByPropertySql(typeof(T), dic, out param);
638 using (IDbProvider provider = new SqlProvider())
639 {
640 return BaseHelper.ConvertToList<T>(BaseHelper.ExecuteDataReader(provider, sql, param));
641 }
642 }
643
644 /// <summary>
645 /// 根據多個屬性查詢實體集合
646 /// 該查詢方式附加查詢組建
647 /// </summary>
648 /// <typeparam name="T">類型類</typeparam>
649 /// <param name="dic">屬性鍵值對</param>
650 /// <param name="component">查詢組件</param>
651 /// <returns></returns>
652 public IList<T> GetList<T>(IDictionary<string, object> dic, ConditionComponent component) where T : class
653 {
654 IDataParameter[] param = null;
655 string sql = Factory.CreateQueryByPropertySql(typeof(T),dic,out param,component);
656 using (IDbProvider provider = new SqlProvider())
657 {
658 return BaseHelper.ConvertToList<T>(BaseHelper.ExecuteDataReader(provider, sql, param));
659 }
660 }
661
662 /// <summary>
663 /// 釋放對象內存
664 /// </summary>
665 public void Dispose()
666 {
667 GC.SuppressFinalize(this);
668 }
669 }
670 }
671
自定義的數據庫操作接口:

2 {
3 /// <summary>
4 /// 用戶登錄
5 /// </summary>
6 /// <param name="name">用戶名</param>
7 /// <param name="pass">用戶密碼</param>
8 /// <returns></returns>
9 TabUser GetUser(string name, string pass);
10 }
自定義數據庫操作類:

2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using CommonData.Data.Core.SQLCore;
6 using Office.Entity;
7
8 namespace Office.DAL.DAL
9 {
10 public class TabUserDAL:SqlHelper,ITabUserDAL
11 {
12 /// <summary>
13 /// 用戶登錄
14 /// </summary>
15 /// <param name="name">用戶名</param>
16 /// <param name="pass">用戶密碼(已經MD5加密)</param>
17 /// <returns></returns>
18 public TabUser GetUser(string name, string pass)
19 {
20 TabUser user = new TabUser();
21 user.UserName = name;
22 user.PassWord = pass;
23 user=GetEntity<TabUser>(user, new string[] { "UserName", "PassWord" });
24 return user;
25 }
26 }
27 }
28
這里的四段代碼相信大家都能夠明白其結構的定義,一般采用的方式每張表定義一個數據庫操作接口和一個實現類,而這個操作接口是繼承了公共的數據庫操作接口,而且還是使用的泛型類型,使用泛型類型使得數據抽象話,而后面的操作過程剛好有與此泛化過程對應的處理過程,在此就保障了核心的一致,每個自定的數據庫操作接口都會去繼承公共的數據庫操作類和實現自身的接口,因此每個自定的數據庫操作類就具有了操作上面定義的操作的所有方法。
在這兒結構中,感覺這個地方使用的非常秒,定義的公共接口中定義的操作方法幾乎能后滿足增刪改查的要求,因此這樣就實現了一個ORM操作數據庫的完整功能,我們就可以不需要過多的去關心數據庫到底是怎樣去處理這些方式,我們的任何操作方式都是以對象的方式來操作,不用關系底層的細節實現。當然,任何一個ORM框架都不是能夠替換所有的數據庫操作,有些過于復雜的操作還是需要自定義sql語句來處理。我們只需在自定義的數據庫操作接口中定義相應的方法即可,畢竟這個ORM映射框架也結合了自定義的處理過程,使得程序更加的靈活,可以從多角度去處理。看到這里,對于一個稍微大型的項目,相對于ADO.NET 操作是不是減少了很多代碼。
這個東西畢竟是一個人寫的,漏洞肯定也不少,自己也沒有那么多的時間去測試,只能慢慢的等以后去修改,性能方面的提交,數據復雜度的處理等等問題,在后期的過程中會逐漸來解決這些問題,并與大家分享。如果大家有任何疑問可以留言,或者好的建議可以隨時聯系我。