C# 缓存密钥) 位于MySql.Data.MySqlClient.StoredProcedure.GetParameters(字符串procName) 位于MySql.Data.MySqlClient.StoredProcedure.CheckParameters(字符串spName) 在MySql.Data.MySqlClient.StoredProcedure.Resolve(布尔值) 位于MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior) 位于MySql.Data.MySqlClient.MySqlCommand.ExecuteDbDataReader(CommandBehavior) 在System.Data.Common.DbCommand.ExecuteDbDataReaderAsync(CommandBehavior行为,CancellationToken CancellationToken) at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中 at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(任务任务) 在C:\projects\Dapper\Dapper\SqlMapper.Async.cs中的Dapper.SqlMapper.d_u33`1.MoveNext()处:第468行 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中 在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()中 在C:\Users\cyclone\Desktop\VS Projects\DigitalCookbook\CookbookLibrary\DataAccess\MySqlConnector.d\uu 5.MoveNext()中 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中 在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()中 在C:\Users\cyclone\Desktop\VS Projects\DigitalCookbook\DigitalCookbook\ViewModel\MainWindowModel.d\u 38.MoveNext()中的DigitalCookbook.ViewModel.MainWindowModel.cs:第228行 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中 在System.Runtime.CompilerServices.TaskAwaiter.GetResult()中 位于C:\Users\cyclone\Desktop\VS Projects\DigitalCookbook\DigitalCookbook\ViewModel\MainWindowModel.cs中的DigitalCookbook.ViewModel.MainWindowModel.d.MoveNext():第114行

C# 缓存密钥) 位于MySql.Data.MySqlClient.StoredProcedure.GetParameters(字符串procName) 位于MySql.Data.MySqlClient.StoredProcedure.CheckParameters(字符串spName) 在MySql.Data.MySqlClient.StoredProcedure.Resolve(布尔值) 位于MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior) 位于MySql.Data.MySqlClient.MySqlCommand.ExecuteDbDataReader(CommandBehavior) 在System.Data.Common.DbCommand.ExecuteDbDataReaderAsync(CommandBehavior行为,CancellationToken CancellationToken) at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中 at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(任务任务) 在C:\projects\Dapper\Dapper\SqlMapper.Async.cs中的Dapper.SqlMapper.d_u33`1.MoveNext()处:第468行 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中 在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()中 在C:\Users\cyclone\Desktop\VS Projects\DigitalCookbook\CookbookLibrary\DataAccess\MySqlConnector.d\uu 5.MoveNext()中 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中 在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()中 在C:\Users\cyclone\Desktop\VS Projects\DigitalCookbook\DigitalCookbook\ViewModel\MainWindowModel.d\u 38.MoveNext()中的DigitalCookbook.ViewModel.MainWindowModel.cs:第228行 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中 在System.Runtime.CompilerServices.TaskAwaiter.GetResult()中 位于C:\Users\cyclone\Desktop\VS Projects\DigitalCookbook\DigitalCookbook\ViewModel\MainWindowModel.cs中的DigitalCookbook.ViewModel.MainWindowModel.d.MoveNext():第114行,c#,mysql,stored-procedures,orm,dapper,C#,Mysql,Stored Procedures,Orm,Dapper,这看起来像是Oracle MySQL Connector/NET(又名MySQL.Data)中的一个bug。它看起来不像是我熟悉的bug数据库中的bug;它可能需要作为新的问题提交。(看起来很相似,但不是很明显是同一个问题。) 我建议换成;它是MySQL的另一个ADO.NET库,与Dapper和MySQL Connector/NET具有很好的兼容性。MySqlConnector还具有真正的异步I/O支持,它位于Connector/NET中;如果您想在代码中使用QueryAsync,这一点很重要

这看起来像是Oracle MySQL Connector/NET(又名
MySQL.Data
)中的一个bug。它看起来不像是我熟悉的bug数据库中的bug;它可能需要作为新的问题提交。(看起来很相似,但不是很明显是同一个问题。)

我建议换成;它是MySQL的另一个ADO.NET库,与Dapper和MySQL Connector/NET具有很好的兼容性。MySqlConnector还具有真正的异步I/O支持,它位于Connector/NET中;如果您想在代码中使用
QueryAsync
,这一点很重要

如果您想继续使用Oracle的MySQL Connector/NET,您可以通过在连接字符串中添加
CheckParameters=false
来解决这个问题。请注意,这可能是对代码的一次突破性更改;如果将设置设置为false,则必须手动确保添加到每个
CommandType.storedProcess
MySqlCommand
的参数与数据库的顺序完全相同(因为MySql.Data将不再为您修复这些参数)

更新:查看Connector/NET源代码后,您的数据库中似乎有一些不需要的数据。以下两个查询是否生成行?如果是,哪些值是
NULL

SELECT*FROM information\u schema.routines
其中特定的_名称为NULL或
例程_架构为NULL或
例程\u名称为NULL或
例程类型为NULL或
例程_定义为NULL或
是否为空或
sql\u数据\u访问为NULL或
安全类型为NULL或
sql_模式为NULL或
例程\u注释为空或空
定义者为空;
从mysql.proc中选择*
其中特定的_名称为NULL或
db为NULL或
名称为NULL或
类型为NULL或
正文为空或空
是否为空或
sql\u数据\u访问为NULL或
安全类型为NULL或
sql_模式为NULL或
注释为NULL或
定义者为空;

您使用的是什么MySQL服务器(MySQL、MariaDB、Amazon Aurora)以及哪个版本?

这看起来像是Oracle MySQL Connector/NET(又名
MySQL.Data
)中的一个bug。它看起来不像是我熟悉的bug数据库中的bug;它可能需要作为新的问题提交。(看起来很相似,但不是很明显是同一个问题。)

我建议换成;它是MySQL的另一个ADO.NET库,与Dapper和MySQL Connector/NET具有很好的兼容性。MySqlConnector还具有真正的异步I/O支持,它位于Connector/NET中;如果您想在代码中使用
QueryAsync
,这一点很重要

如果您想继续使用Oracle的MySQL Connector/NET,您可以通过在连接字符串中添加
CheckParameters=false
来解决这个问题。请注意,这可能是对代码的一次突破性更改;如果将设置设置为false,则必须手动确保添加到每个
CommandType.storedProcess
MySqlCommand
的参数与数据库的顺序完全相同(因为MySql.Data将不再为您修复这些参数)

更新:查看Connector/NET源代码后,您的数据库中似乎有一些不需要的数据。以下两个查询是否生成行?如果是,哪些值是
NULL

SELECT*FROM information\u schema.routines
其中特定的_名称为NULL或
例程_架构为NULL或
例程\u名称为NULL或
例程类型为NULL或
例程_定义为NULL或
是否为空或
sql\u数据\u访问为NULL或
安全类型为NULL或
sql_模式为NULL或
例程\u注释为空或空
定义者为空;
从mysql.proc中选择*
public class Recipe
{

        [Description("id")]
        public int Id { get; set; }

        [Description("name")]
        public string Title { get; set; }

        [Description("description")]
        public string Description { get; set; }

        [Description("source_site")]
        public string SourceSite { get; set; }
}
public class Helper
{
    public static void SetTypeMaps()
    {
        var recipeMap = new CustomPropertyTypeMap(typeof(Recipe),
            (type, columnName) => type.GetProperties().FirstOrDefault(prop => GetDescriptionFromAttribute(prop) == columnName));

        SqlMapper.SetTypeMap(typeof(Recipe), recipeMap);

        // Other custom mappers omitted
    }
/// This does not work
public async Task<Recipe> GetRecipeByIdAsync1(int id)
{
    using (IDbConnection db = new MySqlConnection(GlobalConfig.CnnString("CookbookTest1")))
    {
        var p = new DynamicParameters();
        p.Add("RecipeId", id, dbType: DbType.Int32, direction: ParameterDirection.Input);

        // This is the line where the exception occurs
        var result = await db.QueryAsync<Recipe>("sp_recipes_GetByRecipeId", p, commandType: CommandType.StoredProcedure); 

        return result.FirstOrDefault();
    }

}

// This also does not work
public async Task<Recipe> GetRecipeByIdAsync2(int id)
{
    using (IDbConnection db = new MySqlConnection(GlobalConfig.CnnString("CookbookTest1")))
    {
        // This is the line where the exception occurs
        var result = await db.QueryAsync<Recipe>("sp_recipes_GetByRecipeId", new {RecipeID = id}, commandType: CommandType.StoredProcedure); 

        return result.FirstOrDefault();
    }

}

// Nor this
public async Task<Recipe> GetRecipeByIdAsync3(int id)
{
    using (IDbConnection db = new MySqlConnection(GlobalConfig.CnnString("CookbookTest1")))
    {
        // This is the line where the exception occurs
        var result = await db.QueryAsync<Recipe>("sp_recipes_GetByRecipeId", new {id}, commandType: CommandType.StoredProcedure); 

        return result.FirstOrDefault();
    }

}

// This works perfectly, but I'm not sure how safe it is
public async Task<Recipe> GetRecipeByIdAsync4(int id)
{
    using (IDbConnection db = new MySqlConnection(GlobalConfig.CnnString("CookbookTest1")))
    {
        var result = await db.QueryAsync<Recipe>($"call sp_recipes_GetByRecipeId({id})"); 

        return result.FirstOrDefault();
    }

}

// And of course, this works, but is horrible practice
public async Task<Recipe> GetRecipeByIdAsync5(int id)
{
    using (IDbConnection db = new MySqlConnection(GlobalConfig.CnnString("CookbookTest1")))
    {
        var result = await db.QueryAsync<Recipe>($"SELECT * FROM recipes WHERE recipes.id = {id}"); 

        return result.FirstOrDefault();
    }

}