在foreach循环中声明时的SQLDataReader对象
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在foreach循环中声明时的SQLDataReader对象相关的知识,希望对你有一定的参考价值。
这是我不时回到的,但还没有找到明确的答案。希望我能在微软保留语言之前得到它(开玩笑......有点)......
这几乎肯定是错的,但这就是我从SQLServer中检索记录的方式......我将每行传递给它的调用者作为IDataRecord并使用SQLDataREader对象来迭代它。我已经读过,如果没有在using语句中声明,应该在使用后关闭datareader。我应该关闭这个吗?
我的SQLDataReader在这样的foreach循环中声明...
IEnumerable<IDataRecord> dataset = Select("SELECT Topic FROM Topics WHERE pti=" + pid + " and Ignore = 0");
foreach (SqlDataReader reader in dataset )
{
string topic = reader.GetString(0);
//... do something
}
我的db调用:
public IEnumerable<IDataRecord> Select(string sql, List<SqlParameter> sparams = null)
{
using (SqlConnection cn = new SqlConnection(ConnString()))
{
cn.Open();
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
if (sparams != null)
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddRange(sparams.ToArray());
}
else
{
cmd.CommandType = CommandType.Text;
}
using (SqlDataReader rdr = cmd.ExecuteReader())
{
if (rdr != null && rdr.FieldCount > 0)
{
while (rdr.Read())
{
yield return rdr;
}
}
}
}
cn.Close();
}
}
答案
实际上没有什么可以关闭的。代码中的可关闭阅读器对象是使用连接的对象,但它会被using
方法中的Select
语句自动关闭。
我认为你这样做的方式非常罕见。如果你能够改变方法签名,你可以通过做一个List<>
简单地返回一个cast
,然后像这样删除yield
:
public List<IDataRecord> Select(string sql , List<SqlParameter> sparams = null)
{
using (SqlConnection cn = new SqlConnection (ConnectionString))
{
cn.Open ( );
using (SqlCommand cmd = new SqlCommand (sql , cn))
{
if (sparams != null)
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddRange (sparams.ToArray ( ));
}
else
{
cmd.CommandType = CommandType.Text;
}
using (SqlDataReader rdr = cmd.ExecuteReader ( ))
{
return rdr.Cast<IDataRecord> ( ).ToList ( );
}
}
}
}
我在数据库连接类中完成了这个。这很简单,但如果您有任何疑问,请发表评论:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
namespace SqlToDb
{
public class SqlClientData
{
private string connectionstring;
public string ConnectionString { get => connectionstring; set => connectionstring = value; }
public SqlClientData(string connection_string)
{
ConnectionString = connection_string;
}
public T ExecuteScalar<T>(string queryString)
{
using (SqlConnection conn = new SqlConnection (ConnectionString))
{
using (SqlCommand cmd = new SqlCommand (queryString , conn))
{
try
{
conn.Open ( );
var result = cmd.ExecuteScalar ( );
if (Convert.IsDBNull (result) && typeof (T).IsValueType)
return default (T); // if the db value is null, but T is a value type, set T = the default value of the type.
else
return (T) (result);
}
finally
{
conn.Close ( );
} 以上是关于在foreach循环中声明时的SQLDataReader对象的主要内容,如果未能解决你的问题,请参考以下文章
foreach循环上的PowerShell + =添加重复的实例
完成foreach循环后如何在节点js中返回推送的数组响应?