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

使用ADO.NET从SQL Server取数时,能否让DataTable存储非Object类型数据?

解决ADO.NET DataTable中SQL int列的类型转换问题

方法1:预定义DataTable列类型后填充

你可以先手动构建DataTable的结构,指定每一列的.NET类型,再调用DataAdapter.Fill。ADO.NET会匹配列名填充数据,不会覆盖预先定义的列类型,这样就能直接用强类型访问列值,避免冗余转换。

修改你的代码如下:

using System.Data;
using System.Data.SqlClient;

public static DataTable GetEmployeeStatistics(int EmployeeID)
{
    // 预先构建DataTable并指定列类型
    var Tab = new DataTable();
    Tab.Columns.Add("Height", typeof(int));
    Tab.Columns.Add("Weight", typeof(int));
    // 如果Salary列允许为null,改用typeof(int?)适配可空值
    Tab.Columns.Add("Salary", typeof(int));

    var Command = new SqlCommand("Select [Height], [Weight], [Salary] from [Schema].[Employees] Where EmployeeID = @EmployeeID", GrabMySqlConnection());
    Command.Parameters.AddWithValue("@EmployeeID", EmployeeID);
    var Adapter = new SqlDataAdapter(Command);
    
    // 填充已定义好结构的DataTable
    Adapter.Fill(Tab);
    return Tab;
}

使用时直接强类型访问:

// 非空列直接强转
int height = (int)row["Height"];
// 可空列用as关键字安全转换
int? salary = row["Salary"] as int?;

方法2:使用SqlDataReader手动读取(更灵活高效)

如果不想依赖DataTable的预定义结构,也可以用SqlDataReader直接读取强类型数据,这种方式性能更优,还能直接处理null值,同时可以结合自定义类实现完全强类型化:

using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;

// 定义强类型实体类存储数据(推荐)
public class EmployeeStats
{
    public int Height { get; set; }
    public int Weight { get; set; }
    public int? Salary { get; set; } // 适配SQL可空列
}

public static List<EmployeeStats> GetEmployeeStatistics(int EmployeeID)
{
    var statsList = new List<EmployeeStats>();
    using (var conn = GrabMySqlConnection())
    using (var Command = new SqlCommand("Select [Height], [Weight], [Salary] from [Schema].[Employees] Where EmployeeID = @EmployeeID", conn))
    {
        Command.Parameters.AddWithValue("@EmployeeID", EmployeeID);
        conn.Open();
        using (var reader = Command.ExecuteReader())
        {
            while (reader.Read())
            {
                var stats = new EmployeeStats
                {
                    Height = reader.GetInt32(reader.GetOrdinal("Height")),
                    Weight = reader.GetInt32(reader.GetOrdinal("Weight")),
                    Salary = reader.IsDBNull(reader.GetOrdinal("Salary")) ? null : reader.GetInt32(reader.GetOrdinal("Salary"))
                };
                statsList.Add(stats);
            }
        }
    }
    return statsList;
}

这种方式直接得到强类型对象,完全避免了int.Parse这类冗余代码,代码可读性和维护性更好。

注意事项

  • 如果SQL列允许为null,对应的.NET类型要使用可空值类型(int?),避免抛出InvalidCastException。
  • 预定义DataTable列时,列名必须和SQL查询返回的列名完全一致(大小写不敏感,但建议保持一致)。
  • 使用SqlDataReader的GetOrdinal方法可以避免硬编码列索引,提升代码的可维护性。

内容的提问来源于stack exchange,提问作者J. Mini

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 01:02:25