使用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
相关产品推荐
相关产品推荐

