- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有两个问题。
1) 是否应该始终在连接上使用 using 语句?那么,我会在连接上使用它,然后在连接内的阅读器上使用另一个吗?所以我会使用两个 using 语句。
2) 假设您在连接上使用了 using 语句,并且还在连接上返回了一个阅读器。所以你有两个 using 语句。它会创建两个 Try{}Finally{} block 还是只创建一个?
谢谢!
最佳答案
注意这里。您应该始终在任何 实现 IDisposable 的本地对象上使用 using 语句。这不仅包括连接和阅读器,还包括命令。但有时 using 语句的确切位置可能会很棘手。如果你不小心,它可能会导致问题。例如,在 using 语句后面的代码中,在您开始使用它之前将关闭您的阅读器:
DataReader MyQuery()
{
string sql="some query";
using (var cn = new SqlConnection("connection string"))
using (var cmd = new SqlCommand(sql, cn))
{
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
return rdr;
}
}
}
相反,您有四种选择。一种是等待创建 using block ,直到您调用该函数:
DataReader MyQuery()
{
string sql="some query";
using (var cn = new SqlConnection("connection string"))
using (var cmd = new SqlCommand(sql, cn))
{
cn.Open();
return cmd.ExecuteReader();
}
}
using (var rdr = MyQuery())
{
while (rdr.Read())
{
//...
}
}
当然,您仍然需要小心处理那里的连接,这意味着请记住在您使用该函数的任何地方都写一个 using block 。
选项二只是在方法本身中处理查询结果,但这打破了数据层与程序其余部分的分离。第三个选项是让您的 MyQuery() 函数接受一个 Action 类型的参数,您可以在 while (rdr.Read()) 循环中调用它,但这很尴尬。
我通常更喜欢选项四:将数据读取器变成 IEnumerable,如下所示:
IEnumerable<IDataRecord> MyQuery()
{
string sql="some query";
using (var cn = new SqlConnection("connection string"))
using (var cmd = new SqlCommand(sql, cn))
{
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
yield return rdr;
}
}
}
现在一切都将正确关闭,处理它的代码都在一个地方。您还会得到一个不错的奖励:您的查询结果将适用于任何 linq 运算符。
最后,我将在下一次构建一个全新的项目时使用一些新的东西,该项目将 IEnumerable 与传递的委托(delegate)参数相结合:
//part of the data layer
private static IEnumerable<IDataRecord> Retrieve(string sql, Action<SqlParameterCollection> addParameters)
{
//DL.ConnectionString is a private static property in the data layer
// depending on the project needs, it can be implementing to read from a config file or elsewhere
using (var cn = new SqlConnection(DL.ConnectionString))
using (var cmd = new SqlCommand(sql, cn))
{
addParameters(cmd.Parameters);
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
yield return rdr;
}
}
}
然后我将像这样在数据层中使用它:
public IEnumerable<IDataRecord> GetFooChildrenByParentID(int ParentID)
{
//I could easily use a stored procedure name instead, and provide overloads for commandtypes.
return Retrieve(
"SELECT c.*
FROM [ParentTable] p
INNER JOIN [ChildTable] c ON c.ParentID = f.ID
WHERE f.ID= @ParentID", p =>
{
p.Add("@ParentID", SqlDbType.Int).Value = ParentID;
}
);
}
关于c# - 使用陈述题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2571798/
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
显然,我实际上是想创建一个数组,在多次试验 (5000) 中随机分配生日。然后假设每次有 2 - 50 人至少有 2 个生日时,将结果除以 5,000 以获得近似概率。我相信我的循环搞砸了,希望得到一
PYTHON:试图计算摆在不同行星上摆动所需的时间,我对此非常陌生,因此可能有一个简单的解决方案: def main(): print('Period of a pendulum')
在我的 MySQL 表中,有一行标记为“state”。有 3 个可能的值。我如何利用 PHP 将“Unbanned”回显为状态中的“0”?将“禁止”与“1”相对应,将“临时禁止”与“3”相对应? 我如
我的宏代码中有一个 If 公式,但它似乎没有以正确的方式工作。 下面的代码计算 rCell.Offset 并始终将其应用为 True,我有一些示例,其中它等于 112、113、118 等,并且它正在将
这个问题已经有答案了: 已关闭12 年前。 Possible Duplicate: Why do you have to put a 1; at the end of a Perl 5 module?
网上查了一下parent::init();的意思.我所能找到的只是 init() 是初始化一些设置,这些设置希望在每次应用程序运行时出现。谁能准确解释 parent::init() 的含义,比如这两个
这个问题已经有答案了: What does "%.*s" mean in printf? (4 个回答) 已关闭 3 年前。 我试图理解 printf() 但我只熟悉 C++ cout= 0; r--
我正在开发一个试图通过 tsv infile 将数据插入 mysql 数据库的 java 项目。运行该程序时出现以下错误: Exception in thread "main" java.sql.SQ
好的,我正在开发一个新的应用程序,只要我使用相对 View ,一切都运行良好。但是,我想要一个选项卡式布局,所以我将我拥有的内容(到目前为止还不多,因为我刚刚从数据库中读取它并且设置正常)切换到选项卡
我在另一个问题中看到了这个提示,想知道是否有人可以向我解释这究竟是如何工作的? try { return x; } finally { x = null; } 我的意思是,finally 子句是否真的
这个问题已经有答案了: Is it better to wrap code into an 'IF' statement, or is it better to 'short circuit' the
我是一名优秀的程序员,十分优秀!