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

EF调用Select存储过程填充List时ExecuteSqlRaw返回int如何解决

问题原因

你用错了EF Core的数据库操作方法:

  • ExecuteSqlRaw的设计用途是执行非查询类SQL(增、删、改操作),返回值永远是int类型的受影响行数,不会返回查询结果集。
  • 你用object作为返回集合的泛型参数也不符合EF Core的映射规则,EF Core无法将数据库查询结果自动映射为无结构的object类型。
  • 另外你参数传null时直接传C# null、没有指定参数类型,也会导致存储过程调用时出现参数类型/个数不匹配的隐患。
解决步骤

1. 定义强类型返回实体

根据存储过程返回的字段结构,定义属性名、类型完全匹配的实体类,不需要在DbContext中为该实体配置DbSet,EF Core支持直接映射未注册的实体类型,完全适配你DB First不建表对应DbSet的开发模式:

public class AuditTrail
{
    // 以下属性请根据你查询的数据表实际字段调整,保证名称、类型一一对应
    public long Id { get; set; }
    public string OperationUser { get; set; }
    public string OperationContent { get; set; }
    public DateTime OperationTime { get; set; }
}

2. 替换查询方法,修正参数写法

根据你使用的EF Core版本选择对应的查询方法,调用存储过程获取结果集:

EF Core 3.0+ 版本写法

使用Database.SqlQuery<T>方法直接指定返回类型,执行查询:

public List<AuditTrail> GetAuditTrails(DateTime? StartDate, DateTime? EndDate)
{
    List<MySqlParameter> paramList = new List<MySqlParameter>
    {
        new MySqlParameter("@StartDate", MySqlDbType.DateTime)
        {
            Value = StartDate.HasValue ? StartDate.Value : DBNull.Value
        },
        new MySqlParameter("@EndDate", MySqlDbType.DateTime)
        {
            Value = EndDate.HasValue ? EndDate.Value : DBNull.Value
        }
    };

    var auditTrails = this.Database
        .SqlQuery<AuditTrail>($"CALL GET(@StartDate, @EndDate)", paramList.ToArray())
        .ToList();

    return auditTrails;
}

EF Core 2.x/EF6 版本写法

使用Set<T>().FromSqlRaw方法查询:

public List<AuditTrail> GetAuditTrails(DateTime? StartDate, DateTime? EndDate)
{
    List<MySqlParameter> paramList = new List<MySqlParameter>
    {
        new MySqlParameter("@StartDate", MySqlDbType.DateTime)
        {
            Value = StartDate.HasValue ? StartDate.Value : DBNull.Value
        },
        new MySqlParameter("@EndDate", MySqlDbType.DateTime)
        {
            Value = EndDate.HasValue ? EndDate.Value : DBNull.Value
        }
    };

    var auditTrails = this.Set<AuditTrail>()
        .FromSqlRaw($"CALL GET(@StartDate, @EndDate)", paramList.ToArray())
        .ToList();

    return auditTrails;
}
注意事项
  • 存储过程的参数如果需要传空值,必须传DBNull.Value,不能直接传C# null,否则会被ADO.NET连接器判定为参数无效,触发调用错误。
  • 可空类型参数建议显式指定数据库字段类型(比如本例的MySqlDbType.DateTime),避免连接器自动推断类型错误,导致存储过程参数类型不匹配。
  • 不要使用dynamic或者object作为SqlQuery的泛型参数,EF Core的结果映射依赖强类型定义的属性信息,弱类型无法完成字段值的填充。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 08:31:21