数据访问--不关闭连接VS关闭连接
在自己参与实施的项目当中访问数据的都是用Linq to Sql的。也不知道为什么自己还是不太喜欢用Linq,也许是自己没学好吧或是没有发现其中的技巧。总结起来,每次用数据访问层多要先建立一个连接:
DataContext _db = new DataContext();
当然我对于linq的机制也不了解,这是自己感觉每次建立对象的时候都会新建一个连接,忒浪费资源没有效率。
最近发现自己在暑假改版用Linq访问数据写的网站速度很慢。具体原因还不太清楚,不过Linq的使用还是有一定关系的。我并没有权利说Linq的好与不好,只是我现在认为还是用ADO.NET自己写踏实点。开始的时候我也是按以前的开发经验就是每写一个方法的时候去new一个SqlConnection,自己也没有感觉什么。例如,之前写的判断用户登录的方法:
public static bool UserExist(string username) { int num = 0; //记录符合查询的 记录数 string cmdtxt = "select count(*) from Users where UserName=@username"; SqlParameter UserName = new SqlParameter("@username", username); SqlConnection conn = new SqlConnection(connString); SqlCommand cmd = new SqlCommand(cmdtxt, conn); cmd.Parameters.Add(UserName); conn.Open(); num = Convert.ToInt32(cmd.ExecuteScalar()); conn.Close(); if (num > 0) { if (num != 1) ;//记录到系统异常日志中 return true; } else { return false; } }
最近两天一直在设计家园志的数据库,发现经常会涉及权限的判断。一张网页会用到好多访问数据库的方法,例如判断一个相册的访问权限上面:
- 需要从数据库读出该相册的权限设置;
- 从数据库查询当前用户与主人的关系;
- 密码的判断;
这样就需要访问数据库好多次了,我想如果在加载一张页面的时候需要不断的进行conn.Open()和conn.Close()了。我对这样的重复操作的印象不好啊,做在那里空想这个肯定不好肯定不好,但心里又捏那不准。最后还是决定测试下不同的方法的速度如何。
第一种:关闭连接的:
每个操作的时候都在执行SqlCommand之前打开连接,之后关闭连接。代码:
private static readonly string connString = ConfigurationManager.ConnectionStrings["NcuhomeORGConnectionString"].ConnectionString; public static void InsertError() { SqlConnection conn = new SqlConnection(connString); string cmdtxt = "INSERT INTO [NcuhomeORG].[dbo].[SysErrorLogs]([ErrorLogID],[ErrorMsg] ,[ErrorUrl],[ErrorDatetime])VALUES (1,'hahah','fffff','2009-12-26 11:33:08')"; SqlCommand cmd = new SqlCommand(cmdtxt, conn); conn.Open(); cmd.ExecuteNonQuery(); conn.Close(); }
第二种:在打开连接时先判断,并且不关闭连接:
public static void TryBeforeInsertError() { SqlConnection conn = new SqlConnection(connString); string cmdtxt = "INSERT INTO [NcuhomeORG].[dbo].[SysErrorLogs]([ErrorLogID],[ErrorMsg] ,[ErrorUrl],[ErrorDatetime])VALUES (1,'hahah','fffff','2009-12-26 11:33:08')"; SqlCommand cmd = new SqlCommand(cmdtxt, conn); if (conn.State != ConnectionState.Open) conn.Open(); cmd.ExecuteNonQuery(); }
最后我在一张网页上面测试了,两种方法的执行效率。如下:
protected void Page_Load(object sender, EventArgs e) { Action a = () => test.TryBeforeInsertError(); Action b = () => test.InsertError(); Response.Write("非共享<br />"); Response.Write(test.Profile(b, 20)); Response.Write("<br />共享<br />"); Response.Write(test.Profile(a, 20)); }
结果:
很明显差距很大,多是插入20条记录。关闭连接的是不关闭连接的40倍左右。啊!非共享
execute runs:20;sec:0.362;freq
共享
execute runs:20;sec:0.09;freq
测试计算时间的方法:
public static string Profile(this Action func, int runs) { Stopwatch watch = Stopwatch.StartNew(); for (int i = 0; i < runs; i++) { func(); } watch.Stop(); float sec = watch.ElapsedMilliseconds / 1000.0f; float freq = runs / sec; return String.Format("execute runs:{0};sec:{1};freq", runs, //运行次数 sec, // 运行时间 freq // 平均运行时间 ); }

浙公网安备 33010602011771号