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

C#中DataTable动态添加数据扩展方法空表问题排查

问题分析与解决方案

咱们先一步步排查问题,再给出优化后的可行代码:

1. 先排除调试器的“假象”

在Visual Studio调试窗口里,DataTable默认会显示为{},但这不代表它真的是空的。你得展开这个变量,查看Columns集合是否已经创建了对应AccessLevel的3列,再看Rows集合的数量是否和你传入的enumerable元素数一致。如果这两项都符合预期,那数据其实已经正确添加了,只是调试器的默认显示误导了你。

2. 代码里的性能隐患(虽不是空表直接原因,但必须优化)

你当前代码在循环里反复用Single(s2 => s2.Name.Equals(s))查找属性,每次都是O(n)的时间开销,完全没必要。咱们可以提前把属性名和PropertyInfo的映射用字典存起来,避免重复查找。

3. 确认传入的enumerable是否真的有数据

如果调用这个扩展方法时,传入的IEnumerable<AccessLevel>本身是空的(没有任何实例),那DataTable自然不会有行数据。可以在添加行之前加个判断,或者断点确认enumerable的元素数量。

优化后的完整代码

public static class ModelConverterToTVP
{
    public static SqlMapper.ICustomQueryParameter AsTableValuedParameter<T>(this IEnumerable<T> enumerable, string typeName)
    {
        if (enumerable == null)
            throw new ArgumentNullException(nameof(enumerable));
        if (string.IsNullOrEmpty(typeName))
            throw new ArgumentNullException(nameof(typeName));

        var dataTable = new DataTable();
        // 筛选出可读的公共实例属性
        var readableProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
                                         .Where(p => p.CanRead)
                                         .ToList();

        // 提前建立属性名到PropertyInfo的映射,避免重复查找
        var propertyMap = readableProperties.ToDictionary(p => p.Name);

        // 为DataTable添加列,处理可空类型的情况
        foreach (var prop in readableProperties)
        {
            // 如果是可空值类型,取其底层非空类型作为列类型
            var columnType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
            dataTable.Columns.Add(prop.Name, columnType);
        }

        // 批量添加行数据
        foreach (var obj in enumerable)
        {
            var rowValues = readableProperties.Select(prop => prop.GetValue(obj)).ToArray();
            dataTable.Rows.Add(rowValues);
        }

        return dataTable.AsTableValuedParameter(typeName);
    }
}

额外注意事项

  • 要确保数据库里的**表值类型(TVP)**和你的AccessLevel模型完全匹配:列名大小写一致、数据类型兼容、列顺序对应,否则即使DataTable有数据,也无法正确映射到TVP中,看起来像是“没有数据”。
  • 代码里新增了对可空值类型的处理,如果你后续模型里用到int?这类类型,也能正常生成对应列。

内容的提问来源于stack exchange,提问作者mr-dortaj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:02:31