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

EF Core 7+MariaDb调用存储过程获取数据失败求助

问题描述

我正在使用EF Core 7.0.9、Pomelo.EntityFrameworkCore.MySql 7.0.0搭配MariaDb,执行代码中testResult2行调用存储过程AddressSelectLatestId时出现错误。

相关代码片段:

var testResult2 = await _dbContext.Address
                                  .FromSqlRaw("Call AddressSelectLatestId()")
                                  .Select(x => x.AddressId)
                                  .FirstOrDefaultAsync();

完整仓库代码:

using AutoMapper;
using KadaiS.Dal.Models;
using KadaiS.Domain.Interfaces;
using Microsoft.EntityFrameworkCore;
using System.Data;

namespace KadaiS.Dal.Repository
{
    public class AddressRepository : IAddressRepository
    {
        private readonly KadaiSDbContext _dbContext;
        private readonly IMapper _mapper;

        public AddressRepository(KadaiSDbContext kadaiSDbContext, IMapper mapper)
        {
            _dbContext = kadaiSDbContext;
            _mapper = mapper;
        }
        
        public async Task<int> InsertAddressAsync(Domain.Models.Address address)
        {
            try
            {
                var addressInsert = _mapper.Map<Domain.Models.Address, Models.Address>(address);
                var results = await _dbContext.Database.ExecuteSqlAsync($"Call AddressInsert({addressInsert.Street}, {addressInsert.City}, {addressInsert.Province}, {addressInsert.PostalCode})");

                if(results == 1)
                {
                    var testResult1 = await _dbContext.Address.FromSqlRaw("SELECT MAX(addressId) AS addressId FROM address").Select(x => x.AddressId).FirstOrDefaultAsync();
                    var testResult2 = await _dbContext.Address.FromSqlRaw("Call AddressSelectLatestId()").Select(x => x.AddressId).FirstOrDefaultAsync();
                }

                return 10;
            }
            catch(Exception e)
            {

                throw e;
            }
        }
    }
}

存储过程AddressSelectLatestId定义:

BEGIN
SELECT MAX(addressId) AS addressId FROM address;
END

错误信息:

MySqlConnector.MySqlException: '你的SQL语法有误;请查看对应MariaDB服务器版本的手册,了解在'Call AddressSelectLatestId() ) AS k
LIMIT 1'附近使用的正确语法'

错误原因

EF Core的FromSqlRaw在配合Select、FirstOrDefaultAsync等LINQ方法时,会自动将传入的SQL语句包装成子查询(生成类似SELECT k.AddressId FROM (Call AddressSelectLatestId()) AS k LIMIT 1的SQL),但MariaDB不支持在子查询中直接调用存储过程,因此触发语法错误。

解决方案

直接使用Database.SqlQueryRaw方法执行存储过程,该方法不会对原始SQL进行额外包装,可直接获取结果:

var testResult2 = await _dbContext.Database
    .SqlQueryRaw<int>("Call AddressSelectLatestId()")
    .FirstOrDefaultAsync();
额外提示

代码中ExecuteSqlAsync使用字符串拼接传递参数存在SQL注入风险,建议改用参数化查询:

var results = await _dbContext.Database.ExecuteSqlAsync(
    "Call AddressInsert(@Street, @City, @Province, @PostalCode)",
    new MySqlParameter("@Street", addressInsert.Street),
    new MySqlParameter("@City", addressInsert.City),
    new MySqlParameter("@Province", addressInsert.Province),
    new MySqlParameter("@PostalCode", addressInsert.PostalCode));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:03:14