我有以下方法:
public DataTableReader Get<T>(string sql, T[] parameters, CommandType commandType = CommandType.Text)
{
DataTableReader result;
using (var connection = new MySqlConnection(_connectionString))
{
using (var command = new MySqlCommand())
{
command.CommandType = commandType;
command.CommandText = sql;
command.Connection = connection;
if (parameters != null)
{
command.Parameters.AddRange(parameters);
}
using (var adapter = new MySqlDataAdapter())
{
adapter.SelectCommand = command;
using (var dataTable = new DataTable())
{
adapter.Fill(dataTable);
result = dataTable.CreateDataReader();
} // result contains data here
} // result "loses" data here
}
}
return result;
}
然而,当我到达有关丢失数据的评论时,DataTableReader为空。如果我在它上面的行中放置一个断点(我在其中评论结果包含数据),结果确实包含结果。
发生了什么事?这几乎就像被传递作为参考。
编辑:我应该注意到我有相同的代码连接到SQL Server,其中上面的MySQL特定类的任何实例都被SqlCommand
替换为{{1} 1}}而不是。这一切似乎都有效。
根据要求,这是MSSql的相应方法:
SqlDataAdapter
我已经更新了top方法,以便更快地返回DataReader:
public virtual DataTableReader Get(string sql, SqlParameter[] parameters, CommandType commandType = CommandType.Text)
{
DataTableReader result;
using (var sqlConnection = new SqlConnection(_coreConnectionString))
{
using (var myCommand = new SqlCommand())
{
myCommand.CommandType = commandType;
myCommand.CommandText = sql;
myCommand.Connection = sqlConnection;
if (parameters != null)
{
myCommand.Parameters.AddRange(parameters);
}
using (var myAdapter = new SqlDataAdapter())
{
myAdapter.SelectCommand = myCommand;
using (var myDataTable = new DataTable())
{
myAdapter.Fill(myDataTable);
result = myDataTable.CreateDataReader();
}
}
}
}
return result;
}
我已将变量的赋值保留在return语句的不同行上,因此我可以验证public DataTableReader Get<T>(string sql, T[] parameters, CommandType commandType = CommandType.Text)
{
using (var connection = new MySqlConnection(_connectionString))
{
using (var command = new MySqlCommand())
{
command.CommandType = commandType;
command.CommandText = sql;
command.Connection = connection;
if (parameters != null)
{
command.Parameters.AddRange(parameters);
}
using (var adapter = new MySqlDataAdapter())
{
adapter.SelectCommand = command;
using (var dataTable = new DataTable())
{
adapter.Fill(dataTable);
var reader = dataTable.CreateDataReader();
return reader;
}
}
}
}
}
是否正在填充。但是,当它返回到调用方法时,那里什么都没有。
调用reader
的代码是Get()
,我知道sql有效,因为在返回之前,我会在对象中找到数据。
更多编辑:我一直在做更多的挖掘,因为这真让我烦恼。首先,如果我使用var dt = _dbHelper.Get(sql, parameters)
,则返回数据。但是当然这会创建一个新版本的对象,因此这可能会导致内存问题。
其次(这真让我烦恼)MySqlDataAdapter使用的var reader = dataTable.Copy().CreateDataReader();
方法不是它自己的实现。它使用来自Fill()
的实现(它和DbDataAdapter
都继承自的实现)。那怎么会不一样呢?
答案 0 :(得分:0)
在这一行:
using (var myDataTable = new DataTable())
{
myAdapter.Fill(myDataTable);
result = myDataTable.CreateDataReader();
}
使用你正在使用的代码,当代码从使用中消失时,DataTable被释放,然后你将获得空数据。
尝试声明DataTable并在结束时关闭它。也许使用try/catch/finally
块是一个很好的方法,最后你可以添加dispose。
我希望这会有所帮助