简体   繁体   English

使用ExecuteReaderAsync时无法将DbDataReader类型隐式转换为MySqlDataReader

[英]Cannot implicitly convert type DbDataReader to MySqlDataReader when using ExecuteReaderAsync

I've the following function that allows me to pass in a object and populate that object with the returning data, if any. 我具有以下函数,该函数允许我传入一个对象,并使用返回的数据(如果有)填充该对象。

I've modified the function so that it can be called asynchronously. 我已经修改了该函数,以便可以异步调用它。

public static async Task<MySqlDataReader> MySQLReturnReader(string sName, List<MySqlParameter> oParameters, Action<MySqlDataReader> fn)
{
    using (MySqlConnection oConn = new MySqlConnection(MasterConn))
    {
        await oConn.OpenAsync();

        using (MySqlCommand oMySqlCommand = new MySqlCommand(sName, oConn))
        {
           oMySqlCommand.CommandType = CommandType.StoredProcedure;

            if (oParameters != null)
            {
                foreach (MySqlParameter oPar in oParameters)
                {
                    oMySqlCommand.Parameters.Add(oPar);
                }
            }

            oMySqlCommand.Connection.Open();

            using (MySqlDataReader oReader = oMySqlCommand.ExecuteReaderAsync())
            {
               fn(oReader);
            }

        }
    }
    return;
}

My class object is something like; 我的课堂对象是这样的;

public class MyClass
{
     public int Id {get;set;}
     public string Name {get;set;}
     ...
}

The function can be called like 该函数可以像

 List<MyClass> oMyClassList = new List<MyClass>();
 List<MySqlParameter> oParams = new List<MySqlParameter>();

 List<int> Ids = new List<int>(500);
 Ids.Add(1);
 Ids.Add(2);
 ...
 Ids.Add(499);

 foreach(int Id in Ids)
 {
    MySQLReturnReader("SPCheck", oParams, oRes =>
        {
                while (oRes.Read())
                {
                   MyClass oMyClass = new MyClass();                      
                   oMyClass.Id = Convert.ToInt32(oRes["Id"]);                       
                   oMyClass.Name = oRes["Name"].ToString();
                }

                oMyClassList.Add(oMyClass);
        }
        );


 }

The problem is I'm getting the compilation error of 'Cannot implicitly convert type 'System.Threading.Tasks.Task' to 'MySql.Data.MySqlClient.MySqlDataReader'. 问题是我遇到“无法将类型'System.Threading.Tasks.Task'隐式转换为'MySql.Data.MySqlClient.MySqlDataReader'的编译错误。 Where am I going wrong ? 我要去哪里错了?

I'm wanting to use ExecuteReaderAsync in this way, as the Stored procedure called is very complex and would prefer to run the requests in parallel. 我想以这种方式使用ExecuteReaderAsync,因为调用的存储过程非常复杂,并且希望并行运行请求。

In your code, you have: 在您的代码中,您具有:

using (MySqlDataReader oReader = oMySqlCommand.ExecuteReaderAsync())

The compiler error Cannot implicitly convert type 'System.Threading.Tasks.Task' to 'MySql.Data.MySqlClient.MySqlDataReader' means that you need to use the await keyword to "unwrap" the task returned by ExecuteReaderAsync : 编译器错误Cannot implicitly convert type 'System.Threading.Tasks.Task' to 'MySql.Data.MySqlClient.MySqlDataReader'意味着您需要使用await关键字“解包” ExecuteReaderAsync返回的任务:

using (MySqlDataReader oReader = await oMySqlCommand.ExecuteReaderAsync())

Note however that if you're using the official MySql.Data package, this call won't actually execute asynchronously. 但是请注意,如果您使用的是官方的MySql.Data包,则此调用实际上不会异步执行。 The Async methods in the MySql.Data connector aren't asynchronous; MySql.Data连接器中的Async方法不是异步的。 they block on network I/O and only return when the DB operation is complete. 它们在网络I / O上阻塞,仅在DB操作完成时返回。 (For a much more detailed discussion, see this question and its top answer .) MySQL bug #70111 reports this problem in the MySQL connector. (有关更详细的讨论,请参见此问题及其最佳答案 。) MySQL Bug#70111在MySQL连接器中报告了此问题。

To get truly asynchronous DB operations, you'll have to wait until that bug is fixed, or switch to a different connector. 为了获得真正的异步DB操作,您必须等到该错误修复后,或切换到其他连接器。 I've been developing a new, fully async connector that should be a drop-in replacement for MySql.Data; 我一直在开发一个新的,完全异步的连接器,该连接器应替代MySql.Data; to try it out, install MySqlConnector from NuGet ; 要尝试,请从NuGet安装MySqlConnector its source is at GitHub . 它的来源在GitHub上

This most likely indicates that the library you're using doesn't support ExecuteReaderAsync() , so you're just calling the default implementation inherited from DbCommand . 这很可能表明您正在使用的库不支持ExecuteReaderAsync() ,因此您只是在调用从DbCommand继承的默认实现。 This is why it returns the general DbDataReader (instead of the MySQL-specific one). 这就是为什么它返回常规DbDataReader (而不是特定于MySQL的DbDataReader )的原因。 And this also means that your code won't actually be asynchronous, the default version of ExecuteReaderAsync() is just a synchronous wrapper around ExecuteReader() . 而这也意味着你的代码实际上不会是异步的,默认的版本ExecuteReaderAsync()仅仅是围绕着同步封装ExecuteReader()

So, I think you should directly use the old ExecuteReader() , until your library adds support for ExecuteReaderAsync() . 因此,我认为您应该直接使用旧的ExecuteReader() ,直到您的库添加了对ExecuteReaderAsync()支持。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM