You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 5用EF Core调用MySQL存储过程传字符串参数格式错误求助

问题原因和解决方案

根因分析

  • 你当前的FromSqlRaw参数传递逻辑存在错误:自行将@param1、@param2等参数名拼接到CALL语句的括号中,而EF Core的FromSqlRaw对MySQL提供程序默认仅支持位置占位符(格式为{0}、{1}),不会识别SQL语句中自定义的命名参数。当传入字符串参数时,EF Core尝试直接将字符串值拼入SQL语句却没有自动加引号,就会触发格式错误;int类型参数不需要引号,因此可以正常运行。
  • 若传入的字符串参数为null,未显式配置参数的可空属性,也会触发类型转换异常。

修复代码

通用存储过程执行类修改

直接替换原有拼接参数名的逻辑,改为生成位置占位符,同时添加空值处理:

public async Task<List<T>> ExecuteStoredProcedure(string nameProcedure, List<MySqlParameter> parameters = null)
{
    try
    {
        using (var data = new ContextBase(_optionBuilder))
        {
            parameters ??= new List<MySqlParameter>();
            // 生成对应数量的位置占位符
            var placeholders = Enumerable.Range(0, parameters.Count).Select(i => $"{{{i}}}");
            string executeSql = $"CALL {nameProcedure}({string.Join(", ", placeholders)})";

            // 处理参数为空的场景
            foreach (var param in parameters)
            {
                if (param.Value == null)
                {
                    param.IsNullable = true;
                    param.Value = DBNull.Value;
                }
            }

            var responseData = await data.Set<T>().FromSqlRaw(executeSql, parameters.ToArray())
                                        .AsNoTracking()
                                        .ToListAsync();
            return responseData;
        }
    }
    catch (Exception ex)
    {
        // 原有错误日志逻辑保持不变即可
        ErrorLog error = new ErrorLog();
        error.Error = ex.Message;
        error.Description = "Error encountered DB Procedure Execute ***. Message:" + ex.Message + " when getting the Generic Procedure Execute";
        error.Section = "RepositoryProcedureGenerics.cs";
        error.Layer = "Infra";
        error.Date = DateTime.Now;
        await this.CreateError(error);
        return null;
    }
}

控制器代码可选优化

不需要强制指定MySqlDbType,参数类型会自动适配,也可以简化写法:

public async Task<IActionResult> ExecProcedure([FromQuery(Name = "param1")] int param1, [FromQuery(Name = "param2")] string param2)
{
    List<MySqlParameter> listParameters = new List<MySqlParameter>();
    // 直接传值即可,不需要手动指定类型
    listParameters.Add(new MySqlParameter("@param1", param1));
    listParameters.Add(new MySqlParameter("@param2", param2));

    string sp_name = "test_sp";
    List<Test> test = await _procedureExecutor.ExecuteStoredProcedure(sp_name, listParameters);
    return Ok(test);
}

验证说明

修改后不需要调整存储过程的参数类型,int、text、varchar等类型的参数都可以正常传递,空字符串、null值场景也兼容。


内容的提问来源于stack exchange,提问作者Allen Prado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 05:24:04