对于程序员来说,分页读取数据再熟悉不过了。所以,在这里,我只是简单提点意见。欢迎大家拍砖。
1、存储过程:很多人可能认为,存储过程速度很快。但我看来,不是。通用的分页存储过程,也是带有拼装sql语句的。何来更快?再说,存储过程并不是所有的数据库都支持的,比如:access。对于普通的网站来说,是不是用的上存储过程,还得仔细衡量。sql数据库空间是比较贵的。个人认为:存储过程的好处就是:取得的数据,一次性发送给应用程序。
2、sql语句,什么top之类的。但是写起来麻烦。特别是对那些类似搜索来说 ,搜索条件复杂,多字段排序,top语句的效率也是个问题。当然,要是top语句,写起来有sqlite或mysql的limit语句那样轻松,估计大家都会选择这个写法的。
3、数据控件或装配器,比如:.net中的DataAdapter,其中提供的可用于分页的Fill方法。有时,我觉得,这个可能比上面两个都要有优势的多。对于DataAdapter,我几乎没用到。个人习惯问题。
对于上面的3点,以及看了petshop4中的一个分页方法,我把它和SmartDataReader结合起来,形成一个可以分页的DataReader。
这个SmartDataReader,原先是网络上一个网友(至于叫什么,我记不清了。只记得什么不可不知的。net辅助类),我以自己的想法,加以改造,并加入的分页的功能。
缺点,也是很明显的,但我希望贴出来,有人可以指点一二,或者如何改进,让它真的可以作为分页的一个小型工具。
目前,我也实际用于开发中。
1 using System;
2 using System.Collections.Generic;
3 using System.Data;
4 using System.Globalization;
5
6 namespace DarkArchon.Data
7 {
8 /// <summary>
9 /// 一种基于DataReader的快速访问数据集
10 /// </summary>
11 public sealed class SmartDataReader : IDisposable
12 {
13 /// <summary>
14 /// 数据集读取器
15 /// </summary>
16 private IDataReader objDataReader;
17 private CompareInfo copinfo = CultureInfo.CurrentCulture.CompareInfo;
18 /// <summary>
19 /// 委托定义
20 /// </summary>
21 /// <returns></returns>
22 public delegate bool ReadEvent();
23 /// <summary>
24 /// 声明委托
25 /// </summary>
26 public ReadEvent Read { get; private set; }
27 private string[] columns;
28 /// <summary>
29 /// 构造函数
30 /// </summary>
31 /// <param name="reader">读取器</param>
32 public SmartDataReader(IDataReader reader)
33 {
34 objDataReader = reader;
35 InitColumn(reader);
36 Read = new ReadEvent(reader.Read);
37 }
38 /// <summary>
39 /// 构造器,构造可用于分页的记录集
40 /// </summary>
41 /// <param name="reader">读取器</param>
42 /// <param name="pageSize">分页大小</param>
43 /// <param name="pageIndex">当前页码</param>
44 public SmartDataReader(IDataReader reader, int pageSize, int pageIndex)
45 {
46 objDataReader = reader;
47 if (pageSize < 1)
48 {
49 throw new Exception("pageSize必须大于0");
50 }
51 if (pageIndex < 1)
52 {
53 throw new Exception("pageIndex必须大于0");
54 }
55 int startRecord = pageSize * (pageIndex - 1);
56 int maxRecords = pageSize;
57 InitPage(reader, startRecord);
58 InitColumn(reader);
59 Read = delegate { return ((maxRecords-- > 0) && objDataReader.Read()); };
60 }
61 /// <summary>
62 /// 关闭
63 /// </summary>
64 public void Close()
65 {
66 objDataReader.Close();
67 }
68 /// <summary>
69 /// 释放资源
70 /// </summary>
71 public void Dispose()
72 {
73 if (objDataReader != null)
74 {
75 if (!objDataReader.IsClosed)
76 {
77 objDataReader.Close();
78 }
79 objDataReader.Dispose();
80 }
81 }
82 /// <summary>
83 /// 获取字段索引
84 /// </summary>
85 /// <param name="columnName">字段名称</param>
86 /// <returns>索引位置,没找到,返回-1。</returns>
87 private int GetOrdinal(string columnName)
88 {
89 int retval = -1;
90 for (int i = 0; i < columns.Length; i++)
91 {
92 if (copinfo.Compare(columnName, columns[i], CompareOptions.IgnoreCase) == 0)
93 {
94 retval = i;
95 break;
96 }
97 }
98 if (-1 == retval)
99 {
100 throw new IndexOutOfRangeException("超出索引范围,未能找到字段:" + columnName);
101 }
102 return retval;
103 }
104 /// <summary>
105 /// 初始化字段列表
106 /// </summary>
107 /// <param name="reader">读取器</param>
108 private void InitColumn(IDataReader reader)
109 {
110 columns = new string[reader.FieldCount];
111 for (int i = 0; i < columns.Length; i++)
112 {
113 columns[i] = reader.GetName(i);
114 }
115 }
116 /// <summary>
117 /// 初始化读取器,用于分页。
118 /// </summary>
119 /// <param name="reader">读取器</param>
120 /// <param name="startRecord">起止位置</param>
121 private void InitPage(IDataReader reader, int startRecord)
122 {
123 while ((0 < startRecord) && (reader.Read()))
124 {
125 startRecord--;
126 }
127 }
128 /// <summary>
129 /// 获取下一记录集
130 /// </summary>
131 /// <returns></returns>
132 public bool NextResult()
133 {
134 Read = new ReadEvent(objDataReader.Read);
135 return objDataReader.NextResult();
136 }
137 /// <summary>
138 /// 获取字段值
139 /// </summary>
140 /// <param name="i">字段索引号</param>
141 /// <returns></returns>
142 public object this[int i]
143 {
144 get { return objDataReader.GetValue(i); }
145 }
146 /// <summary>
147 /// 获取字段值
148 /// </summary>
149 /// <param name="columnName">字段名</param>
150 /// <returns></returns>
151 public object this[string columnName]
152 {
153 get { return objDataReader.GetValue(GetOrdinal(columnName)); }
154 }
155 /// <summary>
156 /// 获取字段值,默认值:false
157 /// </summary>
158 /// <param name="columnName">字段名</param>
159 /// <returns></returns>
160 public bool GetBoolean(string columnName)
161 {
162 return GetBoolean(columnName, false);
163 }
164 /// <summary>
165 /// 获取字段值
166 /// </summary>
167 /// <param name="columnName">字段名</param>
168 /// <param name="defval">默认值</param>
169 /// <returns></returns>
170 public bool GetBoolean(string columnName, bool defval)
171 {
172 int index = GetOrdinal(columnName);
173 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetBoolean(index));
174 }
175 /// <summary>
176 /// 获取字段值,默认值:MinValue。
177 /// </summary>
178 /// <param name="columnName">字段名</param>
179 /// <returns></returns>
180 public byte GetByte(string columnName)
181 {
182 return GetByte(columnName, byte.MinValue);
183 }
184 /// <summary>
185 /// 获取字段值
186 /// </summary>
187 /// <param name="columnName">字段名</param>
188 /// <param name="defval">默认值</param>
189 /// <returns></returns>
190 public byte GetByte(string columnName, byte defval)
191 {
192 int index = GetOrdinal(columnName);
193 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetByte(index));
194 }
195 /// <summary>
196 /// 获取字段值,默认值:MinValue。
197 /// </summary>
198 /// <param name="columnName">字段名</param>
199 /// <returns></returns>
200 public DateTime GetDateTime(string columnName)
201 {
202 return GetDateTime(columnName, DateTime.MinValue);
203 }
204 /// <summary>
205 /// 获取字段值
206 /// </summary>
207 /// <param name="columnName">字段名</param>
208 /// <param name="defval">默认值</param>
209 /// <returns></returns>
210 public DateTime GetDateTime(string columnName, DateTime defval)
211 {
212 int index = GetOrdinal(columnName);
213 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetDateTime(index));
214 }
215 /// <summary>
216 /// 获取字段值,默认值:MinValue。
217 /// </summary>
218 /// <param name="columnName">字段名</param>
219 /// <returns></returns>
220 public decimal GetDecimal(string columnName)
221 {
222 return GetDecimal(columnName, decimal.MinValue);
223 }
224 /// <summary>
225 /// 获取字段值
226 /// </summary>
227 /// <param name="columnName">字段名</param>
228 /// <param name="defval">默认值</param>
229 /// <returns></returns>
230 public decimal GetDecimal(string columnName, decimal defval)
231 {
232 int index = GetOrdinal(columnName);
233 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetDecimal(index));
234 }
235 /// <summary>
236 /// 获取字段值,默认值:MinValue。
237 /// </summary>
238 /// <param name="columnName">字段名</param>
239 /// <returns></returns>
240 public double GetDouble(string columnName)
241 {
242 return GetDouble(columnName, double.MinValue);
243 }
244 /// <summary>
245 /// 获取字段值。
246 /// </summary>
247 /// <param name="columnName">字段名</param>
248 /// <param name="defval">默认值</param>
249 /// <returns></returns>
250 public double GetDouble(string columnName, double defval)
251 {
252 int index = GetOrdinal(columnName);
253 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetDouble(index));
254 }
255 /// <summary>
256 /// 获取字段值,默认值:MinValue。
257 /// </summary>
258 /// <param name="columnName">字段名</param>
259 /// <returns></returns>
260 public float GetFloat(string columnName)
261 {
262 return GetFloat(columnName, float.MinValue);
263 }
264 /// <summary>
265 /// 获取字段值
266 /// </summary>
267 /// <param name="columnName">字段名</param>
268 /// <param name="defval">默认值</param>
269 /// <returns></returns>
270 public float GetFloat(string columnName, float defval)
271 {
272 int index = GetOrdinal(columnName);
273 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetFloat(index));
274 }
275 /// <summary>
276 /// 获取字段值,默认值:MinValue。
277 /// </summary>
278 /// <param name="columnName">字段名</param>
279 /// <returns></returns>
280 public int GetInt(string columnName)
281 {
282 return GetInt(columnName, int.MinValue);
283 }
284 /// <summary>
285 /// 获取字段值
286 /// </summary>
287 /// <param name="columnName">字段名</param>
288 /// <param name="defval">默认值</param>
289 /// <returns></returns>
290 public int GetInt(string columnName, int defval)
291 {
292 int index = GetOrdinal(columnName);
293 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetInt32(index));
294 }
295 /// <summary>
296 /// 获取字段值,默认值:MinValue。
297 /// </summary>
298 /// <param name="columnName">字段名</param>
299 /// <returns></returns>
300 public short GetShort(string columnName)
301 {
302 return GetShort(columnName, short.MinValue);
303 }
304 /// <summary>
305 /// 获取字段值
306 /// </summary>
307 /// <param name="columnName">字段名</param>
308 /// <param name="defval">默认值</param>
309 /// <returns></returns>
310 public short GetShort(string columnName, short defval)
311 {
312 int index = GetOrdinal(columnName);
313 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetInt16(index));
314 }
315 /// <summary>
316 /// 获取字段值,默认值:MinValue。
317 /// </summary>
318 /// <param name="columnName">字段名</param>
319 /// <returns></returns>
320 public long GetLong(string columnName)
321 {
322 return GetLong(columnName, long.MinValue);
323 }
324 /// <summary>
325 /// 获取字段值
326 /// </summary>
327 /// <param name="columnName">字段名</param>
328 /// <param name="defval">默认值</param>
329 /// <returns></returns>
330 public long GetLong(string columnName, long defval)
331 {
332 int index = GetOrdinal(columnName);
333 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetInt64(index));
334 }
335 /// <summary>
336 /// 获取字段值,默认值:String.Empty。
337 /// </summary>
338 /// <param name="columnName">字段名</param>
339 /// <returns></returns>
340 public string GetString(string columnName)
341 {
342 return GetString(columnName, string.Empty);
343 }
344 /// <summary>
345 /// 获取字段值
346 /// </summary>
347 /// <param name="columnName">字段名</param>
348 /// <param name="defval">默认值</param>
349 /// <returns></returns>
350 public string GetString(string columnName, string defval)
351 {
352 int index = GetOrdinal(columnName);
353 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetString(index));
354 }
355 }
356 }
2 using System.Collections.Generic;
3 using System.Data;
4 using System.Globalization;
5
6 namespace DarkArchon.Data
7 {
8 /// <summary>
9 /// 一种基于DataReader的快速访问数据集
10 /// </summary>
11 public sealed class SmartDataReader : IDisposable
12 {
13 /// <summary>
14 /// 数据集读取器
15 /// </summary>
16 private IDataReader objDataReader;
17 private CompareInfo copinfo = CultureInfo.CurrentCulture.CompareInfo;
18 /// <summary>
19 /// 委托定义
20 /// </summary>
21 /// <returns></returns>
22 public delegate bool ReadEvent();
23 /// <summary>
24 /// 声明委托
25 /// </summary>
26 public ReadEvent Read { get; private set; }
27 private string[] columns;
28 /// <summary>
29 /// 构造函数
30 /// </summary>
31 /// <param name="reader">读取器</param>
32 public SmartDataReader(IDataReader reader)
33 {
34 objDataReader = reader;
35 InitColumn(reader);
36 Read = new ReadEvent(reader.Read);
37 }
38 /// <summary>
39 /// 构造器,构造可用于分页的记录集
40 /// </summary>
41 /// <param name="reader">读取器</param>
42 /// <param name="pageSize">分页大小</param>
43 /// <param name="pageIndex">当前页码</param>
44 public SmartDataReader(IDataReader reader, int pageSize, int pageIndex)
45 {
46 objDataReader = reader;
47 if (pageSize < 1)
48 {
49 throw new Exception("pageSize必须大于0");
50 }
51 if (pageIndex < 1)
52 {
53 throw new Exception("pageIndex必须大于0");
54 }
55 int startRecord = pageSize * (pageIndex - 1);
56 int maxRecords = pageSize;
57 InitPage(reader, startRecord);
58 InitColumn(reader);
59 Read = delegate { return ((maxRecords-- > 0) && objDataReader.Read()); };
60 }
61 /// <summary>
62 /// 关闭
63 /// </summary>
64 public void Close()
65 {
66 objDataReader.Close();
67 }
68 /// <summary>
69 /// 释放资源
70 /// </summary>
71 public void Dispose()
72 {
73 if (objDataReader != null)
74 {
75 if (!objDataReader.IsClosed)
76 {
77 objDataReader.Close();
78 }
79 objDataReader.Dispose();
80 }
81 }
82 /// <summary>
83 /// 获取字段索引
84 /// </summary>
85 /// <param name="columnName">字段名称</param>
86 /// <returns>索引位置,没找到,返回-1。</returns>
87 private int GetOrdinal(string columnName)
88 {
89 int retval = -1;
90 for (int i = 0; i < columns.Length; i++)
91 {
92 if (copinfo.Compare(columnName, columns[i], CompareOptions.IgnoreCase) == 0)
93 {
94 retval = i;
95 break;
96 }
97 }
98 if (-1 == retval)
99 {
100 throw new IndexOutOfRangeException("超出索引范围,未能找到字段:" + columnName);
101 }
102 return retval;
103 }
104 /// <summary>
105 /// 初始化字段列表
106 /// </summary>
107 /// <param name="reader">读取器</param>
108 private void InitColumn(IDataReader reader)
109 {
110 columns = new string[reader.FieldCount];
111 for (int i = 0; i < columns.Length; i++)
112 {
113 columns[i] = reader.GetName(i);
114 }
115 }
116 /// <summary>
117 /// 初始化读取器,用于分页。
118 /// </summary>
119 /// <param name="reader">读取器</param>
120 /// <param name="startRecord">起止位置</param>
121 private void InitPage(IDataReader reader, int startRecord)
122 {
123 while ((0 < startRecord) && (reader.Read()))
124 {
125 startRecord--;
126 }
127 }
128 /// <summary>
129 /// 获取下一记录集
130 /// </summary>
131 /// <returns></returns>
132 public bool NextResult()
133 {
134 Read = new ReadEvent(objDataReader.Read);
135 return objDataReader.NextResult();
136 }
137 /// <summary>
138 /// 获取字段值
139 /// </summary>
140 /// <param name="i">字段索引号</param>
141 /// <returns></returns>
142 public object this[int i]
143 {
144 get { return objDataReader.GetValue(i); }
145 }
146 /// <summary>
147 /// 获取字段值
148 /// </summary>
149 /// <param name="columnName">字段名</param>
150 /// <returns></returns>
151 public object this[string columnName]
152 {
153 get { return objDataReader.GetValue(GetOrdinal(columnName)); }
154 }
155 /// <summary>
156 /// 获取字段值,默认值:false
157 /// </summary>
158 /// <param name="columnName">字段名</param>
159 /// <returns></returns>
160 public bool GetBoolean(string columnName)
161 {
162 return GetBoolean(columnName, false);
163 }
164 /// <summary>
165 /// 获取字段值
166 /// </summary>
167 /// <param name="columnName">字段名</param>
168 /// <param name="defval">默认值</param>
169 /// <returns></returns>
170 public bool GetBoolean(string columnName, bool defval)
171 {
172 int index = GetOrdinal(columnName);
173 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetBoolean(index));
174 }
175 /// <summary>
176 /// 获取字段值,默认值:MinValue。
177 /// </summary>
178 /// <param name="columnName">字段名</param>
179 /// <returns></returns>
180 public byte GetByte(string columnName)
181 {
182 return GetByte(columnName, byte.MinValue);
183 }
184 /// <summary>
185 /// 获取字段值
186 /// </summary>
187 /// <param name="columnName">字段名</param>
188 /// <param name="defval">默认值</param>
189 /// <returns></returns>
190 public byte GetByte(string columnName, byte defval)
191 {
192 int index = GetOrdinal(columnName);
193 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetByte(index));
194 }
195 /// <summary>
196 /// 获取字段值,默认值:MinValue。
197 /// </summary>
198 /// <param name="columnName">字段名</param>
199 /// <returns></returns>
200 public DateTime GetDateTime(string columnName)
201 {
202 return GetDateTime(columnName, DateTime.MinValue);
203 }
204 /// <summary>
205 /// 获取字段值
206 /// </summary>
207 /// <param name="columnName">字段名</param>
208 /// <param name="defval">默认值</param>
209 /// <returns></returns>
210 public DateTime GetDateTime(string columnName, DateTime defval)
211 {
212 int index = GetOrdinal(columnName);
213 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetDateTime(index));
214 }
215 /// <summary>
216 /// 获取字段值,默认值:MinValue。
217 /// </summary>
218 /// <param name="columnName">字段名</param>
219 /// <returns></returns>
220 public decimal GetDecimal(string columnName)
221 {
222 return GetDecimal(columnName, decimal.MinValue);
223 }
224 /// <summary>
225 /// 获取字段值
226 /// </summary>
227 /// <param name="columnName">字段名</param>
228 /// <param name="defval">默认值</param>
229 /// <returns></returns>
230 public decimal GetDecimal(string columnName, decimal defval)
231 {
232 int index = GetOrdinal(columnName);
233 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetDecimal(index));
234 }
235 /// <summary>
236 /// 获取字段值,默认值:MinValue。
237 /// </summary>
238 /// <param name="columnName">字段名</param>
239 /// <returns></returns>
240 public double GetDouble(string columnName)
241 {
242 return GetDouble(columnName, double.MinValue);
243 }
244 /// <summary>
245 /// 获取字段值。
246 /// </summary>
247 /// <param name="columnName">字段名</param>
248 /// <param name="defval">默认值</param>
249 /// <returns></returns>
250 public double GetDouble(string columnName, double defval)
251 {
252 int index = GetOrdinal(columnName);
253 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetDouble(index));
254 }
255 /// <summary>
256 /// 获取字段值,默认值:MinValue。
257 /// </summary>
258 /// <param name="columnName">字段名</param>
259 /// <returns></returns>
260 public float GetFloat(string columnName)
261 {
262 return GetFloat(columnName, float.MinValue);
263 }
264 /// <summary>
265 /// 获取字段值
266 /// </summary>
267 /// <param name="columnName">字段名</param>
268 /// <param name="defval">默认值</param>
269 /// <returns></returns>
270 public float GetFloat(string columnName, float defval)
271 {
272 int index = GetOrdinal(columnName);
273 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetFloat(index));
274 }
275 /// <summary>
276 /// 获取字段值,默认值:MinValue。
277 /// </summary>
278 /// <param name="columnName">字段名</param>
279 /// <returns></returns>
280 public int GetInt(string columnName)
281 {
282 return GetInt(columnName, int.MinValue);
283 }
284 /// <summary>
285 /// 获取字段值
286 /// </summary>
287 /// <param name="columnName">字段名</param>
288 /// <param name="defval">默认值</param>
289 /// <returns></returns>
290 public int GetInt(string columnName, int defval)
291 {
292 int index = GetOrdinal(columnName);
293 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetInt32(index));
294 }
295 /// <summary>
296 /// 获取字段值,默认值:MinValue。
297 /// </summary>
298 /// <param name="columnName">字段名</param>
299 /// <returns></returns>
300 public short GetShort(string columnName)
301 {
302 return GetShort(columnName, short.MinValue);
303 }
304 /// <summary>
305 /// 获取字段值
306 /// </summary>
307 /// <param name="columnName">字段名</param>
308 /// <param name="defval">默认值</param>
309 /// <returns></returns>
310 public short GetShort(string columnName, short defval)
311 {
312 int index = GetOrdinal(columnName);
313 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetInt16(index));
314 }
315 /// <summary>
316 /// 获取字段值,默认值:MinValue。
317 /// </summary>
318 /// <param name="columnName">字段名</param>
319 /// <returns></returns>
320 public long GetLong(string columnName)
321 {
322 return GetLong(columnName, long.MinValue);
323 }
324 /// <summary>
325 /// 获取字段值
326 /// </summary>
327 /// <param name="columnName">字段名</param>
328 /// <param name="defval">默认值</param>
329 /// <returns></returns>
330 public long GetLong(string columnName, long defval)
331 {
332 int index = GetOrdinal(columnName);
333 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetInt64(index));
334 }
335 /// <summary>
336 /// 获取字段值,默认值:String.Empty。
337 /// </summary>
338 /// <param name="columnName">字段名</param>
339 /// <returns></returns>
340 public string GetString(string columnName)
341 {
342 return GetString(columnName, string.Empty);
343 }
344 /// <summary>
345 /// 获取字段值
346 /// </summary>
347 /// <param name="columnName">字段名</param>
348 /// <param name="defval">默认值</param>
349 /// <returns></returns>
350 public string GetString(string columnName, string defval)
351 {
352 int index = GetOrdinal(columnName);
353 return (objDataReader.IsDBNull(index) ? defval : objDataReader.GetString(index));
354 }
355 }
356 }
357