使用MySqlDataAdapter时,为什么DataTableReader会丢失其数据?

时间:2014-11-20 12:53:31

标签: c# mysql

我有以下方法:

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都继承自的实现)。那怎么会不一样呢?

1 个答案:

答案 0 :(得分:0)

在这一行:

using (var myDataTable = new DataTable())
                {
                    myAdapter.Fill(myDataTable);
                    result = myDataTable.CreateDataReader();
                }

使用你正在使用的代码,当代码从使用中消失时,DataTable被释放,然后你将获得空数据。

尝试声明DataTable并在结束时关闭它。也许使用try/catch/finally块是一个很好的方法,最后你可以添加dispose。

我希望这会有所帮助