这让我很头疼。我知道这个问题(或它的至少变种)已被多次询问,但在一个标记为重复之前请考虑以下代码:
string myConnectionString = myConnectionString = ConfigurationManager.ConnectionStrings["DBCS"].ToString();
SqlConnection mySQLConnection;
SqlCommand mySQLCommand;
SqlDataReader mySQLDataReader;
using (mySQLConnection = new SqlConnection(myConnectionString))
{
mySQLCommand = new SqlCommand("SELECT TOP 1 * FROM Table ORDER BY Id DESC", mySQLConnection);
mySQLCommand.Connection = mySQLConnection;
mySQLCommand.Connection.Open();
using(mySQLDataReader = mySQLCommand.ExecuteReader())
{
if (mySQLDataReader.HasRows)
{
if (mySQLConnection.State == ConnectionState.Open)
{
while (mySQLDataReader.Read())
{
//Perform Logic : If the last record being returned meets some condition then call the below method
MethodCalled();
}
}
}
}
MessageBox.Show("Connection state: " + mySQLConnection.State);
}
我想找到一种方法:
while-loop
完成阅读并且不再有行但我只是继续SqlException
说明以下内容:
读取器关闭时无效尝试调用读取
仅仅从广泛的观察,我可以追踪到错误是由于我返回仅包含一行的数据。问题是,在读取该行之后,编译器返回While(mySQLDataReader.Read()){}
并尝试读取不包含任何行的表。
我尝试了以下内容:
从ExecuteReader()
块中的命令对象中包装using
,以便它一旦完成读取就会自动关闭阅读器和连接:
using(mySQLDataReader = mySQLCommand.ExecuteReader())
{
//Logic performed
}
在<{1}}的右括号之前,我尝试检查sql命令是否还有剩余/返回的行,并在该条件下断开循环很满意:
while-loop
两次尝试均未成功。我怎么能绕过这个?
答案 0 :(得分:3)
必须是以下三件事之一:
Read()
区域外using
使用using
。请注意,Close
阻止会隐式调用您的阅读器上的Dispose
和Read()
。因此,任何using
调用都必须放在using
块内。mySQLDataReader
块的正文明确关闭了读者。这似乎不太可能。DataReader
声明为更高级别。可能是其他一些(异步)代码关闭了读者。这也不太可能。在大多数情况下,您不应该在全球范围内定义using (var mySQLConnection = new SqlConnection(myConnectionString))
{
mySQLCommand = new SqlCommand("SELECT TOP 1 * FROM Table ORDER BY Id DESC", mySQLConnection, mySQLConnection);
mySQLCommand.Connection.Open();
using(mySQLDataReader = mySQLCommand.ExecuteReader())
{
while (mySQLDataReader.Read())
{
//Perform Logic : If the last record being returned meets some condition then call the below method
MethodCalled();
}
}
}
。阅读您现在发布的完整代码块,我建议您进行一些更改。你可以运行以下内容并告诉我们它是否运行:
<ngx-datatable class="material"
[rows]="rows"
[columnMode]="'force'"
[headerHeight]="40"
[footerHeight]="40"
[rowHeight]="30"
[externalPaging]="true"
[limit]="50"
[selectionType]="'checkbox'">
<ngx-datatable-column
[width]="30"
[sortable]="false"
[canAutoResize]="false"
[draggable]="false"
[resizeable]="false"
[headerCheckboxable]="true"
[checkboxable]="true">
</ngx-datatable-column>
<ngx-datatable-column name="Name">
<ng-template let-value="value" ngx-datatable-cell-template>
<div class="redNumber">{{value}}</div>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="Title"></ngx-datatable-column>
<ngx-datatable-column name="company"></ngx-datatable-column>
<ngx-datatable-column name="Status" [cellClass]="getStatusClass">
</ngx-datatable-column>
<ngx-datatable-column name="Last connexion"></ngx-datatable-column>
如果此版本运行正常,我们可以更好地挖掘问题。
答案 1 :(得分:1)
如果没有要迭代的数据,while循环将根本不执行。你需要检查HasRows吗?此外,在创建数据读取器时应使用CommandBehavior.CloseConnection。这将确保在您阅读完基础连接后关闭它。
Should if call SqlDataReader.HasRows if I am calling SqlReader.Read
using (SqlConnection mySQLConnection = new SqlConnection(myConnectionString))
{
using (SqlCommand mySQLCommand = new SqlCommand("SELECT TOP 1 * FROM Table ORDER BY Id DESC", mySQLConnection))
{
mySQLConnection.Open();
SqlDataReader mySQLDataReader = mySQLCommand.ExecuteReader(CommandBehavior.CloseConnection);
while (mySQLDataReader.Read())
{
//Code logic here
}
// this call to mySQLDataReader.Close(); will close the underlying connection
mySQLDataReader.Close();
}
MessageBox.Show("Connection state: " + mySQLConnection.State);
}