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

使用Entity Framework Core调用存储过程遇SqlNullValueException如何处理?

解决.NET 9中调用存储过程返回NULL值时抛出SqlNullValueException的问题

问题根源

这个异常不是因为存储过程返回空列表,而是存储过程返回的结果集中存在NULL值,但对应的VystupyOdkazyModel实体属性是不可空的值类型(如int、DateTime等),EF Core在将数据库NULL值映射到不可空值类型属性时会抛出SqlNullValueException。

解决步骤

1. 修正实体模型的可空属性

检查VystupyOdkazyModel类的所有属性,找到与存储过程返回字段对应、但可能为NULL的属性,将其改为可空类型:

// 示例:将不可空的int改为可空int?
public int? SomeNullableField { get; set; }
// 将不可空的DateTime改为可空DateTime?
public DateTime? SomeNullableDate { get; set; }

确保所有可能返回NULL的数据库字段,都对应实体中的可空属性。

2. 安全传递存储过程参数(避免SQL注入)

你当前使用字符串插值传递参数存在SQL注入风险,同时可能导致可空参数处理异常,改用SqlParameter传递参数:

public async Task<List<VystupyOdkazyModel>> GetOdkazyAsync(int projekt, short typK, DateTime dateFrom, DateTime dateTo, int CurrProgram, int? misto)
{
    var parameters = new[]
    {
        new SqlParameter("@projekt", projekt),
        new SqlParameter("@typK", typK),
        new SqlParameter("@from", dateFrom),
        new SqlParameter("@to", dateTo),
        new SqlParameter("@program", CurrProgram),
        // 处理可空参数:如果misto为null,传入DBNull.Value
        new SqlParameter("@misto", misto.HasValue ? (object)misto.Value : DBNull.Value)
    };

    // 使用FromSqlRaw执行存储过程
    var result = await _db.VystupyOdkazy.FromSqlRaw(
        "EXECUTE dbo.sp_GetSumareOdkazu @projekt, @typK, @from, @to, @program, @misto", 
        parameters
    ).ToListAsync();

    // 空列表直接返回,无需额外判断(ToListAsync返回空列表而非null)
    return result ?? new List<VystupyOdkazyModel>();
}

3. 正确处理异常捕获

你当前的try-catch块直接throw,等于没有处理异常。如果需要捕获并处理该异常,可以在GetOdkazyAsync内部添加捕获逻辑,或者在调用处处理:

try
{
    Odkazy = await GetOdkazyAsync(projekt, typK, dateFrom, dateTo, (int)CurrProgram, misto);
}
catch (SqlNullValueException ex)
{
    // 处理NULL映射异常,比如返回空列表或记录日志
    Odkazy = new List<VystupyOdkazyModel>();
    // 可选:记录日志
    // _logger.LogError(ex, "存储过程返回NULL值导致映射失败");
}
catch (Exception ex)
{
    // 处理其他异常
    // _logger.LogError(ex, "调用存储过程时发生错误");
    throw;
}

额外说明

  • ToListAsync在没有数据时会返回空列表而非null,所以你原来的if (result != null)判断是多余的,可以直接返回result。
  • 确保存储过程返回的结果集字段名、类型与VystupyOdkazyModel的属性完全匹配,否则也可能导致映射异常。

内容的提问来源于stack exchange,提问作者Jan Šalomoun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:02:01