使用SqlDataReader作为资源的习惯用法
继这个问题之后,我发现自己一遍又一遍地编写以下代码:
SqlCommand command = new SqlCommand(); // Code to initialize command with what we want to do using (SqlConnection connection = openConnection()) { command.Connection = connection; using (SqlDataReader dataReader = thisCommand.ExecuteReader()) { while (dataReader.Read()) { // Do stuff with results } } }
必须嵌套两个using语句是相当繁琐的。 有没有办法告诉 SqlDataReader它拥有该命令,并告诉命令它拥有该连接?
如果有办法做到这一点,那么我可以写一个辅助方法,可以像这样调用:
// buildAndExecuteCommand opens the connection, initializes the command // with the connection and returns the SqlDataReader object. Dispose of the // SqlDataReader to dispose of all resources that were acquired using(SqlDataReader reader = buildAndExecuteCommand(...)) { // Do stuff with reader }
或者我必须咬紧牙关并在SqlDataReader上编写自己的包装器?
有一件事就是编写一个为您处理的方法,用每个结果回调一个委托。 例如:
using (SqlConnection connection = openConnection()) { command.Connection = connection; ExecuteReaderWithCommand(command, reader => { // Do stuff with the result here. }); }
然后ExecuteReaderWithCommand将是这样的:
public static void ExecuteReaderWithCommand(SqlCommand command, Action action) { using (SqlDataReader dataReader = thisCommand.ExecuteReader()) { while (reader.Read()) { action(reader); } } }
如果你愿意,你可以在SqlCommand
上使它成为一个扩展方法。 哎呀,如果你想要的话,你可以去城里让它为你打开连接……你越能抽象出“打开/使用/关闭”的想法,就越好。
您可以编写类似这样的内容,并告诉dataReader在使用后关闭连接:
SqlCommand command = new SqlCommand(); command.Connection = openConnection(); using (SqlDataReader dataReader = command.ExecuteReader(CommandBehavior.CloseConnection)) { while (dataReader.Read()) { // Do stuff with results } }
但是,最好显式关闭连接,因为连接打开和ExecuteReader之间可能会发生exception。
你必须自己构建包装器。 或者你可以使用ORM,如果这是一个选项。
为什么不看看企业库DAAB ?
以下是文档中的代码示例,根据您的方案进行了调整:
Database db = DatabaseFactory.CreateDatabase(); using (IDataReader reader = db.ExecuteReader(CommandType.Text, "SQL here..." )) { while (reader.Read()) { action(reader); } }
使用诸如Action
public IDataReader ExecuteReader(string commandText, CommandType commandType, IDbDataParameter[] parameters) { IDbConnection connection = CreateConnection(); try { IDbCommand command = CreateCommand(commandText, connection); command.CommandType = commandType; AppendParameters(command, parameters); connection.Open(); return command.ExecuteReader(CommandBehavior.CloseConnection); } catch { connection.Close(); throw; } }
- 我应该使用List 还是仅使用Action 来跟踪IObservable的订户?
- 如何使用Aggregate()将几个独立的LINQ查询重写为单个查询?
- String.Format计算预期args的数量
- 如何使用GDI +绘制环形(甜甜圈)?
- XmlTextWriter序列化问题
- Image.Save()抛出exception“Value不能为null ./r/nParameter name:encoder”
- C#SendKeys.SendWait到另一个进程的对话框(notepad.exe)
- 将关闭按钮(红色x)添加到.NET工具提示
- .Net 3.5上的Web服务客户端应用程序的SSL和过时TLS(1.0和1.1)