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

如何用ExecuteReader()高效将数据添加至List并解决空值异常

使用ExecuteReader()读取全量数据时遇SqlNullValueException的解决方法

问题场景

  • UI中设按钮用于展示表内剩余记录,控制器通过带LIMIT和OFFSET的SELECT *语句实现需求,用ExecuteReader()读取数据并转换为自定义Run类的List集合
  • SSMS中无论LIMIT设多大都能正常执行,超过表行数时会返回所有行;但WebAPI里LIMIT>200时抛出System.Data.SqlTypes.SqlNullValueException,异常信息为Data is Null. This method or property cannot be called on Null values.,LIMIT<200时则能正常返回Run类型列表
  • 怀疑流式读取转Run类的步骤有问题,不确定是否需要先把所有数据存入List、关闭连接后再转换为Run实例

问题根源

数据库返回的部分字段存在空值,从SqlDataReader读取数据转换到Run类时,直接调用了不允许空值的读取方法(比如reader.GetString()、reader.GetInt32()等),读取到空值时就触发了异常。前200条数据恰好没有空值,所以能正常执行,超过200后读到带空值的记录就抛出了异常。

解决方法

1. 读取数据时增加DbNull检查

读取每个字段前先判断是否为DBNull.Value,再执行赋值逻辑,示例代码:

using (var reader = cmd.ExecuteReader())
{
    var runs = new List<Run>();
    while (reader.Read())
    {
        var run = new Run
        {
            Id = reader.IsDBNull(reader.GetOrdinal("Id")) ? null : reader.GetInt32(reader.GetOrdinal("Id")),
            Name = reader.IsDBNull(reader.GetOrdinal("Name")) ? null : reader.GetString(reader.GetOrdinal("Name")),
            // 其他字段按此逻辑逐个检查空值
        };
        runs.Add(run);
    }
    return runs;
}

2. 确保自定义Run类支持空值

类中的属性需定义为可空类型(比如用int?替代int,string本身支持空值),否则VS会阻止空值赋值操作,示例:

public class Run
{
    public int? Id { get; set; }
    public string Name { get; set; }
    // 其他需要支持空值的属性同理定义
}

额外说明

不需要先把所有数据存入中间List再转换,ExecuteReader()流式读取时直接处理空值即可解决问题,核心是处理数据库空值与自定义类属性的兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:21:35