1
ASP.NET中一般都是使用SQL Server作为后台数据库。一般的ASP.NET数据库操作示例程序都是使用单独的数据访问,就是说每个页面都写连接到数据库,存取数据,关闭数据库的代码。这种方式带来了一些弊端,一个就是如果你的数据库改变了,你必须一个页面一个页面的去更改数据库连接代码。
2
第二个弊端就是代码冗余,很多代码都是重复的,不必要的。
3
因此,我试图通过一种一致的数据库操作类来实现ASP.NET种的数据访问。
4
5
我们就拿一般网站上都会有的新闻发布系统来做例子,它需要一个文章数据库,我们把这个数据库命名为 News_Articles。新闻发布系统涉及到 发布新闻,展示文章,管理文章等。
6
7
一篇文章一般都会有标题,作者,发表时间,内容,另外我们需要把它们编号。我们把它写成一个类,叫 Article 类,代码如下:
8
9
//Article.cs
10
using System;
11
12
namespace News_Articles.Data
13

{
14
/**//// <summary>
15
/// Summary description for Article.
16
/// </summary>
17
public class Article
18
{
19
private int _id; //文章编号
20
private string _author; //文章的作者
21
private string _topic; //文章的标题
22
private DateTime _postTime; //文章的发表时间
23
private string _content; //文章内容
24
25
public int ID
26
{
27
get
{ return _id;}
28
set
{ _id = value;}
29
}
30
public string Author
31
{
32
get
{ return _author; }
33
set
{ _author = value; }
34
}
35
public string Topic
36
{
37
get
{ return _topic; }
38
set
{ _topic = value; }
39
}
40
public string Content
41
{
42
get
{ return _content; }
43
set
{ _content = value; }
44
}
45
public DateTime PostTime
46
{
47
get
{ return _postTime; }
48
set
{ _postTime = value; }
49
}
50
}
51
}
52
53
54
然后我们写一个文章集合类 ArticleCollection
55
代码如下
56
57
58
程序代码
59
60
//ArticleCollection.cs
61
using System[color=#0000ff];
62
using System.Collections;
63
64
namespace News_Articles.Data
65

{
66
/**//// <summary>
67
/// 文章的集合类,继承于 ArrayList
68
/// </summary>
69
public class ArticleCollection : ArrayList
70
{
71
public ArticleCollection() : base()
72
{
73
}
74
75
public ArticleCollection(ICollection c) : base(c)
76
{
77
}
78
}
79
}[/color]
80
81
82
这个类相当于一个ASP.NET中的DataSet(其实两者很不一样),很简单,主要的目的是把将很多篇文章集合,以便在ASP.NET页面中给DataGrid或者DataList作为数据源,以显示文章。
83
84
现在我们可以实现对News_Articles数据库的操作了,我说过,这是一个数据库操作类。不妨命名为 ArticleDb。实现如下:
85
86
程序代码
87
88
//ArticleDb.cs
89
using System;
90
using System.Configuration;
91
using System.Data;
92
using System.Data.SqlClient;
93
94
namespace News_Articles.Data
95

{
96
/**//**//**//// <summary>
97
/// 数据库操作类,实现文章数据库的读取,插入,更新,删除
98
/// </summary>
99
public class ArticleDb
100
{
101
private SqlConnection _conn; //SQL Server 数据库连接
102
private string _articledb = "News_Articles"; //SQL Server 文章数据库表
103
104
/**//**//**//// <summary>
105
/// 类的初始化,设置数据库连接
106
/// </summary>
107
public ArticleDb()
108
{
109
_conn = new SqlConnection(ConfigurationSettings.AppSettings["connectionString"]);
110
}
111
112
/**//**//**//// <summary>
113
/// 打开数据库连接
114
/// </summary>
115
public void Open()
116
{
117
if(_conn.State == ConnectionState.Closed)
118
_conn.Open();
119
}
120
121
/**//**//**//// <summary>
122
/// 关闭数据库连接
123
/// </summary>
124
public void Close()
125
{
126
if(_conn.State == ConnectionState.Open)
127
_conn.Close();
128
}
129
130
/**//**//**//// <summary>
131
/// 读取数据库中所有的 文章
132
/// </summary>
133
/// <returns>ArticleCollection</returns>
134
public ArticleCollection GetArticles()
135
{
136
ArticleCollection articles = new ArticleCollection();
137
string sql = "Select * FROM " + _articledb;
138
SqlCommand cmd = new SqlCommand(sql,_conn);
139
SqlDataReader dr = cmd.ExecuteReader();
140
while(dr.Read())
141
{
142
Article art = PopulateArticle(dr);
143
articles.Add(art);
144
}
145
dr.Close();
146
return articles;
147
}
148
149
150
/**//**//**//// <summary>
151
/// 给定一个文章编号, 读取数据库中的一篇文章
152
/// </summary>
153
/// <returns>Article</returns>
154
public Article GetArticle(int articleId)
155
{
156
string sql = "Select * FROM " + _articledb + "Where ID='" + articleId + "'";
157
SqlCommand cmd = new SqlCommand(sql,_conn);
158
SqlDataReader dr = cmd.ExecuteReader();
159
Article article = PopulateArticle(dr);
160
dr.Close();
161
return article;
162
}
163
164
/**//**//**//// <summary>
165
/// 更新数据库记录,注意需要设定文章的编号
166
/// </summary>
167
/// <param name="article"></param>
168
public void UpdateArticle(Article article)
169
{
170
string sql = "Update " + _articledb +" SET Topic=@topic,Author=@author,Content=@content,PostTime=@postTime"
171
+ " Where ID = @articleId";
172
SqlCommand cmd = new SqlCommand(sql,_conn);
173
174
cmd.Parameters.Add("@articleId",SqlDbType.Int,4).Value = article.ID;
175
cmd.Parameters.Add("@topic",SqlDbType.NVarChar,100).Value = article.Topic;
176
cmd.Parameters.Add("@author",SqlDbType.NVarChar,100).Value = article.Author;
177
cmd.Parameters.Add("@content",SqlDbType.NText).Value = article.Content;
178
cmd.Parameters.Add("@postTime",SqlDbType.DateTime).Value = article.PostTime;
179
180
cmd.ExecuteNonQuery();
181
182
}
183
184
185
/**//**//**//// <summary>
186
/// 取出数据库中特定作者发表的文章
187
/// </summary>
188
/// <param name="author"></param>
189
/// <returns>ArticleCollection</returns>
190
public ArticleCollection GetArticlesByAuthor(string author)
191
{
192
string sql = "Select * FROM " + _articledb +" Where Author='" + author + "'";
193
SqlCommand cmd = new SqlCommand(sql, _conn);
194
195
ArticleCollection articleCollection = new ArticleCollection();
196
197
SqlDataReader dr = cmd.ExecuteReader();
198
199
while (dr.Read())
200
{
201
Article a = PopulateArticle(dr);
202
articleCollection.Add(a);
203
}
204
dr.Close();
205
return articleCollection;
206
207
}
208
209
210
/**//**//**//// <summary>
211
/// 删除给定编号的一篇文章
212
/// </summary>
213
/// <param name="articleID"></param>
214
public void DeleteArticle(int articleID)
215
{
216
string sql = "Delete FROM " + _articledb + " Where ID='" + articleID + "'";
217
SqlCommand cmd = new SqlCommand(sql, _conn);
218
cmd.ExecuteNonQuery();
219
}
220
221
222
223
224
/**//**//**//// <summary>
225
/// 通过 SqlDataReader 生成文章对象
226
/// </summary>
227
/// <param name="dr"></param>
228
/// <returns></returns>
229
private Article PopulateArticle(SqlDataReader dr)
230
{
231
Article art = new Article();
232
233
art.ID = Convert.ToInt32(dr["ID"]);
234
art.Author = Convert.ToString(dr["Author"]);
235
art.Topic = Convert.ToString(dr["Topic"]);
236
237
art.Content = Convert.ToString(dr["Content"]);
238
art.PostTime= Convert.ToDateTime(dr["PostTime"]);
239
240
return art;
241
}
242
243
244
245
/**//**//**//// <summary>
246
/// 增加一篇文章到数据库中,返回文章的编号
247
/// </summary>
248
/// <param name="article"></param>
249
/// <returns>刚刚插入的文章的编号</returns>
250
public int AddPost(Article article)
251
{
252
string sql = "Insert INTO " + _articledb +"(Author,Topic,Content,PostTime)"+
253
"VALUES(@author, @topic, @content, @postTime) "+
254
"Select @postID = @@IDENTITY";
255
SqlCommand cmd = new SqlCommand(sql,_conn);
256
cmd.Parameters.Add("@postID",SqlDbType.Int,4);
257
cmd.Parameters["@postID"].Direction = ParameterDirection.Output;
258
259
cmd.Parameters.Add("@author",SqlDbType.NVarChar,100).Value = article.Author;
260
cmd.Parameters.Add("@topic",SqlDbType.NVarChar,400).Value = article.Topic;
261
cmd.Parameters.Add("@content",SqlDbType.Text).Value = article.Content;
262
cmd.Parameters.Add("@postTime",SqlDbType.DateTime).Value = article.PostTime;
263
264
cmd.ExecuteNonQuery();
265
266
article.ID = (int)cmd.Parameters["@postID"].Value;
267
return article.ID;
268
269
}
270
}
271
}
272
273
274
275
基本的框架已经出来了。如果我们要在一个ASP.NET页面中显示文章数据库 News_Artices的数据,那么仅仅需要添加一个 DataGrid 或者 DataList,然后绑定数据源。例如
276
在 Default.aspx 中添加一个 DataGrid ,命名为 ArticlesDataGrid,在 后台代码 Default.aspx.cs 中添加
277
278
程序代码
279
using News_Articles.Data;
280
281
282
并在 Page_Load 中添加如下的代码:
283
284
285
程序代码
286
private void Page_Load(object sender, System.EventArgs e)
287

{
288
// Put user code to initialize the page here
289
ArticleDb myArticleDb = new ArticleDb();
290
myArticleDb.Open();
291
ArticleCollection articles = myArticleDb.GetArticles();
292
this.ArticlesDataGrid.DataSource = articles;
293
if(!Page.IsPostBack)
294
{
295
this.ArticlesDataGrid.DataBind();
296
}
297
298
myArticleDb.Close();
299
}
300
301
302
这样就可以实现读取文章数据库中所有文章。
303
如果需要删除一篇文章那么添加如下代码:
304
305
程序代码
306
307
//删除编号为 1 的文章
308
myArticleDb.DeleteArticle(1);
309
310
插入一篇文章,代码如下:
311
312
313
程序代码
314
//插入一篇新的文章,不需要指定文章编号,文章编号插入成功后由SQL Server返回。
315
Article newArticle = new Article();
316
newArticle.Author = "Willmove";
317
newArticle.Topic = "测试插入一篇新的文章";
318
newArticle.Content = "这是我写的文章的内容";
319
newArticle.PostTime = DateTime.Now;
320
int articleId = myArticleDb.AddPost(newArticle);
321
322
323
更新一篇文章,代码如下:
324
325
326
程序代码
327
//更新一篇文章,注意需要指定文章的编号
328
Article updateArticle = new Article();
329
updateArticle.ID = 3; //注意需要指定文章的编号
330
updateArticle.Author = "Willmove";
331
updateArticle.Topic = "测试更新数据";
332
updateArticle.Content = "这是我更新的文章的内容";
333
updateArticle.PostTime = DateTime.Now;
334
myArticleDb.UpdateArticle(updateArticle);
335
336
337
以上只是一个框架,具体的实现还有很多细节没有列出来。但是基于上面的框架,你可以比较方便的写出对数据库操作的代码。另外一个建议就是把上面的数据库访问的 SQL 语句写成数据库存储过程,比如 添加一篇文章:
338
339
程序代码
340
Create PROCEDURE AddPost
341
(
342
@ID int OUTPUT,
343
@Author nvarchar(100),
344
@Topic nvarchar(100),
345
@Content ntext,
346
@PostTime datetime
347
)
348
AS
349
Insert INTO News_Articles(Author, Topic, Content, PostTime) VALUES (@Author, @Topic, @Content, @PostTime);
350
Select @ID = @@IDENTITY
351
GO
352
353
354
附1:News_Articles 数据库的字段
355
356
357
程序代码
358
359
字段名 描述 数据类型 长度 是否可为空
360
ID 文章编号 int 4 否
361
Topic 文章标题 nvarchar 100 否
362
Author 作者 nvarchar 100 是
363
Content 文章内容 ntext 16 否
364
PostTime 发表时间 datetime 8 否
365
366
其中 PostTime 的默认值可以设置为(getutcdate())
367
368
SQL 语句是
369
370
Create TABLE [News_Articles] (
371
[ID] [int] IDENTITY (1, 1) NOT NULL ,
372
[Topic] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NOT NULL ,
373
[Author] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,
374
[Content] [ntext] COLLATE Chinese_PRC_CI_AS NOT NULL ,
375
[PostTime] [datetime] NOT NULL CONSTRAINT [DF_News_Articles_PostTime] DEFAULT (getutcdate())
376
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
377
GO
378
379
380
附2:News_Articles 项目源代码
381
说明:打开项目文件 News_Articles.csproj 之前需要先设置 虚拟路径 News_Articles,或者在 News_Articles.csproj.webinfo 中更改设置。要正常运行还必须安装有SQL Server 并且安装了文章数据库 News_Articles。项目源代码的根目录下有 SQL 文本文件。
382
383

2

3

4

5

6

7

8

9

10

11

12

13



14


15

16

17

18



19

20

21

22

23

24

25

26



27



28



29

30

31



32



33



34

35

36



37



38



39

40

41



42



43



44

45

46



47



48



49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65



66


67

68

69

70



71

72



73

74

75

76



77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95



96


97

98

99

100



101

102

103

104


105

106

107

108



109

110

111

112


113

114

115

116



117

118

119

120

121


122

123

124

125



126

127

128

129

130


131

132

133

134

135



136

137

138

139

140

141



142

143

144

145

146

147

148

149

150


151

152

153

154

155



156

157

158

159

160

161

162

163

164


165

166

167

168

169



170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185


186

187

188

189

190

191



192

193

194

195

196

197

198

199

200



201

202

203

204

205

206

207

208

209

210


211

212

213

214

215



216

217

218

219

220

221

222

223

224


225

226

227

228

229

230



231

232

233

234

235

236

237

238

239

240

241

242

243

244

245


246

247

248

249

250

251



252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287



288

289

290

291

292

293

294



295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383
