asp.net2.0已经出来好久了,由于许多的原因一直没有使用,一个月前才开始使用VS2005写东西。
这一个月里又重新学习了一下基础知识,比如多态、接口了什么的。
既然已经到了2.0了嘛,那么以前的数据访问的方式要不要变一下呢?简单看了一下,感觉还是我的那种方式好,至少时我已经用习惯了。那么用.net2.0的方法重写一遍吧。
看了一下Framework 2.0的代码,发现一个问题。虽然表面上ADO.NET的使用没有什么变化(加了一些功能,原来由的功能没有变),但是内部实现有比较大的变化,原来的接口的“工作”都改成了抽象基类。
正好可以利用这个特性来改一下支持多数据库的部分。
数据访问类分成了两个DLL,共 3+3个部分。
本着把变化提出来的思想,我把变化的地方编译成一个DLL,相对不变的地方编译成另一个DLL。
变化的地方又分为三个部分:读取web.config里的信息,基类,写错误日志。
不变的地方分为三个部分:SQL语句部分(静态函数),存储过程部分(需要实例化),填充实体类部分。
下面是容易变化的DLL代码:

读取Webconfig文件
1
using System;
2
using System.Web.Configuration;
3
4
namespace JYK.DataAccessLibrary
5

{
6
public class WebConfig
7
{
8
9
public static readonly string ConnectionString = System.Web.Configuration.WebConfigurationManager.AppSettings["ConnString"];
10
11
读取webconfig里的连接字符串并返回#region 读取webconfig里的连接字符串并返回
12
/**//// <summary>
13
/// 返回连接字符串
14
/// </summary>
15
/// <returns></returns>
16
//public static string ConnectionString()
17
//{
18
// return System.Web.Configuration.WebConfigurationManager.AppSettings["ConnString"];
19
//}
20
#endregion
21
22
读取webconfig里的数据库类型的信息并返回#region 读取webconfig里的数据库类型的信息并返回
23
/**//// <summary>
24
/// 返回数据库类型
25
/// 1:SQL 2000 SQL2005
26
/// 2:Orcale
27
/// 3:OleDb
28
/// 4:ODBC
29
/// </summary>
30
/// <returns></returns>
31
public static int DataBaseType()
32
{
33
string show = System.Web.Configuration.WebConfigurationManager.AppSettings["DataBaseType"];
34
if (show == null)
35
return 1;
36
else
37
return Int32.Parse(show);
38
39
}
40
#endregion
41
42
读取webconfig里的是否显示出错信息并返回#region 读取webconfig里的是否显示出错信息并返回
43
/**//// <summary>
44
/// 返回是否显示出错的SQL语句
45
/// </summary>
46
/// <returns></returns>
47
public static bool isShowErrorSQL()
48
{
49
string show = System.Web.Configuration.WebConfigurationManager.AppSettings["isShowErrorSQL"];
50
if (show == null)
51
{
52
return false;
53
}
54
else
55
{
56
if (show == "0")
57
return false;
58
else
59
return true;
60
}
61
62
}
63
#endregion
64
65
}
66
}
着里的处理并不是太好,只是还没有想到更好的方法。
主要是读取连接字符串和数据库类型。
==================================================
简单工厂,根据数据库类型返回实例对应的实例。
1
sing System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Data;
5
using System.Data.Common;
6
using JYK;
7
8
namespace JYK.DataAccessLibrary
9

{
10
/**//// <summary>
11
/// 返回Connection、Command、DataAdapter
12
/// </summary>
13
public class Factory
14
{
15
16
public static string DataBaseType = WebConfig.DataBaseType();
17
Connection#region Connection
18
/**//// <summary>
19
/// 根据webconfig返回一个Connection的实例。
20
/// </summary>
21
/// <returns></returns>
22
public static DbConnection CreateConnection()
23
{
24
return CreateConnection(DataBaseType);
25
}
26
27
/**//// <summary>
28
/// 返回一个Connection的实例
29
/// </summary>
30
/// <returns></returns>
31
public static DbConnection CreateConnection(int DataBaseType)
32
{
33
switch (DataBaseType)
34
{
35
default:
36
return new System.Data.SqlClient.SqlConnection(WebConfig.ConnectionString);
37
// case 2:
38
// return new ;
39
case 3:
40
return new System.Data.OleDb.OleDbConnection(WebConfig.ConnectionString);
41
case 4:
42
return new System.Data.Odbc.OdbcConnection(WebConfig.ConnectionString);
43
}
44
45
}
46
#endregion
47
48
Command#region Command
49
public static DbCommand CreateCommand()
50
{
51
return CreateCommand(DataBaseType, "");
52
}
53
54
public static DbCommand CreateCommand(int DataBaseType)
55
{
56
return CreateCommand(DataBaseType, "");
57
}
58
59
public static DbCommand CreateCommand(string sql)
60
{
61
return CreateCommand(DataBaseType, sql);
62
}
63
64
/**//// <summary>
65
/// 返回Command实例,并且设置Connection和CommandText
66
/// </summary>
67
/// <param name="DataBaseType"></param>
68
/// <param name="sql"></param>
69
/// <returns></returns>
70
public static DbCommand CreateCommand(int DataBaseType, string sql)
71
{
72
DbCommand cm = null;
73
cm = new System.Data.SqlClient.SqlCommand(sql, (System.Data.SqlClient.SqlConnection)CreateConnection());
74
return cm;
75
}
76
#endregion
77
78
DataAdapter#region DataAdapter
79
public static DbDataAdapter CreateDataAdapter()
80
{
81
return CreateDataAdapter(DataBaseType, "");
82
}
83
84
public static DbDataAdapter CreateDataAdapter(string sql)
85
{
86
return CreateDataAdapter(DataBaseType, sql);
87
}
88
89
public static DbDataAdapter CreateDataAdapter(int DataBaseType)
90
{
91
return CreateDataAdapter(DataBaseType, "");
92
}
93
94
/**//// <summary>
95
/// 返回DataAdapter的实例,并且设置SelectCommand和CommandText
96
/// </summary>
97
/// <param name="DataBaseType">数据库类型</param>
98
/// <param name="sql">SQL语句</param>
99
/// <returns></returns>
100
public static DbDataAdapter CreateDataAdapter(int DataBaseType,string sql)
101
{
102
DbDataAdapter da = null;
103
da = new System.Data.SqlClient.SqlDataAdapter();
104
da.SelectCommand = CreateCommand(DataBaseType,sql);
105
return da;
106
}
107
108
public static void DbDataAdapterDispose(DbDataAdapter da)
109
{
110
da.SelectCommand.Connection.Close();
111
da.SelectCommand.Connection.Dispose();
112
da.SelectCommand.Dispose();
113
da.Dispose();
114
}
115
#endregion
116
117
}
118
}
119
一、利用了System.Data.Common; 里面的一些基类。
System.Data.Common.DbProviderFactory 还没有研究,好像可以利用它来实现,去掉switch。
但是我觉得数据访问的地方是比较特殊的,
1、数据库的种类是有限的,常用的也就三个(对于.net来说):MS SQL 、Orcale 、Access(属于OleDb),算上不常用的应该超不过十种,全都算上也超不过30种吧。
2、变化慢,出现一种新的数据库要多长时间呢?好长好长吧。
3、运行效率高,访问数据库是很频繁的事情,应该尽量提高运行效率,去掉不必要的地方。
综上所述,我感觉switch更好一点。两外为什么说这里是容易变化的地方呢?因为这里可以做很多的变化。
a、比如说我只用MS SQL,不可能用到其它的数据库,那么我可以把 简化 CreateConnection() 函数,去掉判断的部分,直接返回 SqlConnection()。这样可以提高一点效率。
b、比如我只在MS SQL和 Orcale 之间切换,那么我可以只写两个判断,呵呵,以后再加数据库,再加一条判断就可以了。因为数据库的变换是很慢的,所以改动程序也没有什么麻烦的。
二、这里的处理也不是太好,至少缩小了使用范围,这么写的目的主要是让调用的地方减少点代码。两外也是按照我的习惯来写的。
======================================
记录出错信息的代码
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
5
namespace JYK.DataAccessLibrary
6

{
7
public class WriteLog
8
{
9
设置出错信息#region 设置出错信息
10
/**//// <summary>
11
/// 当发生异常时,所作的处理
12
/// </summary>
13
/// <param name="FunctionName">函数名称</param>
14
/// <param name="commandText">查询语句或者存储过程</param>
15
/// <param name="message">错误信息</param>
16
public static string SetErrorMsg(string FunctionName, string commandText, string message)
17
{
18
//设置返回到上一层的错误信息
19
string errorMsg = FunctionName + "函数出现错误。<BR>错误信息:" + message;
20
if (WebConfig.isShowErrorSQL())
21
{
22
errorMsg += "<BR>查询语句:" + commandText;
23
addLogErr(commandText, errorMsg); //记录到错误日志
24
}
25
else
26
{
27
addLogErr(commandText, errorMsg + "<BR>查询语句:" + commandText); //记录到错误日志
28
}
29
return errorMsg;
30
31
}
32
#endregion
33
34
记录错误日志#region 记录错误日志
35
//如果要使用的话,根据你的需要进行修改。
36
public static void addLogErr(string SPName, string ErrDescribe)
37
{
38
//记录到错误日志
39
string FilePath = System.Web.HttpContext.Current.Server.MapPath("/log/" + DateTime.Now.ToString("yyyyMMdd") + ".txt");
40
System.Text.StringBuilder str = new System.Text.StringBuilder();
41
str.Append(DateTime.Now.ToString());
42
str.Append("\t");
43
str.Append(SPName);
44
str.Append("\t");
45
str.Append(ErrDescribe.Replace("<BR>", ""));
46
str.Append("\r\n");
47
48
System.IO.StreamWriter sw = null;
49
try
50
{
51
sw = new System.IO.StreamWriter(FilePath, true, System.Text.Encoding.Unicode);
52
sw.Write(str.ToString());
53
}
54
catch (Exception ex)
55
{
56
System.Web.HttpContext.Current.Response.Write("没有访问日志文件的权限!或日志文件只读!<BR>" + ex.Message);
57
}
58
finally
59
{
60
if (sw != null)
61
sw.Close();
62
}
63
}
64
#endregion
65
}
66
}
67
这个对于经常在程序里面使用SQL语句的兄弟们是很实用的,因为它会把出错的SQL语句、出错的描述(ex.Message)、函数名称、出错的时间,写到一个文本文件里面。对于查错是很方便的。存储过程的话帮助不是很大,因为存储过程的出错描述总是让人很晕,记录下来帮助也不是很大。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!