这是我不时回到的,但还没有找到明确的答案。希望我能在微软保留语言之前得到它(开玩笑......有点)......
这几乎肯定是错的,但这就是我从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
}
我的数据库电话:
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();
}
}
答案 0 :(得分:1)
实际上没有什么可以关闭的。代码中的可关闭阅读器对象是使用该连接的对象,但它会被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 ( );
}
}
}
}
public List<T> ExecScalarList<T>(string sql , bool exclude_nulls , bool replace_null_with_default)
{
using (SqlConnection conn = new SqlConnection (ConnectionString))
{
using (SqlCommand cmd = new SqlCommand (sql , conn))
{
conn.Open ( );
using (SqlDataReader rdr = cmd.ExecuteReader ( ))
{
var mylist = new List<T> { };
while (rdr.Read ( ))
{
if (!Convert.IsDBNull (rdr[0]) || (exclude_nulls == false && replace_null_with_default == false))
{
mylist.Add ((T) Convert.ChangeType (rdr[0] , typeof (T)));
}
else
{
if (exclude_nulls == false)
{
if (replace_null_with_default == true) mylist.Add (default (T)); // returns the default for the type... not null
}
}
}
return mylist;
}
}
}
}
public List<IDataRecord> ExecReader(string sql)
{
using (SqlConnection conn = new SqlConnection (ConnectionString))
{
using (SqlCommand cmd = new SqlCommand (sql , conn))
{
conn.Open ( );
using (SqlDataReader rdr = cmd.ExecuteReader ( ))
{
return rdr.Cast<IDataRecord> ( ).ToList ( );
}
}
}
}
public int ExecNonQuery(string sql)
{
int result = 0;
using (SqlConnection cn = new SqlConnection (ConnectionString))
{
using (SqlCommand cmd = new SqlCommand (sql , cn))
{
cmd.CommandType = CommandType.Text; // or CommandType.StoredProcedure
cn.Open ( );
try
{
result = (Int32) cmd.ExecuteNonQuery ( ); //returns the number of rows affected
}
finally
{
cn.Close ( );
}
}
}
return result;
}
}
}