1 问题重现

(1)新建项目DBNullExp。项目属性为“控制台应用程序”;

(2)在项目下新建数据集Schools(数据集文件的后缀名为.xsd);

(3)在数据集下新建数据表Students,表字段的定义例如以下表所看到的:

字段名

说明

ID

dc.DataType = Type.GetType("System.Int32");//类型

dc.AutoIncrement = true;//自己主动增量

dc.AutoIncrementSeed = 1;//起始为1

dc.AutoIncrementStep = 1;//步长为1

dc.AllowDBNull = false;//非空

Name

dc.DataType = Type.GetType("System.String");//类型

dc.AllowDBNull = false;//非空

Age

dc.DataType = Type.GetType("System.Int32");//类型

dc.AllowDBNull = true;//可空

Email

dc.DataType = Type.GetType("System.String");//类型

dc.AllowDBNull = true;//可空

(4)向Students数据表插入5条演示样例数据。

Schools.StudentsDataTable sdt = new Schools.StudentsDataTable();
sdt.Rows.Add(new object[] { null, "张三", 25, "zhangsan@sina.com" });
sdt.Rows.Add(new object[] { null, "李四", 23, "lisi@sina.com" });
sdt.Rows.Add(new object[] { null, "王五", 24, "wangwu@sina.com" });
sdt.Rows.Add(new object[] { null, "周六", null, null });
sdt.Rows.Add(new object[] { null, "吴七", 25, "wuqi@sina.com" });

(5)查询数据表sdt,获取当中年龄大于24的学生信息输出到界面。

var newStudentList = sdt.Where(it => it.Age > 25).ToList();
foreach (var s in newStudentList)
{Console.WriteLine(s.Name);
}

(6)执行代码,抛出例如以下图所看到的异常。

2 问题分析与解决

从异常提示信息能够看出,问题出在Students表的Age字段上,异常信息中指出Age字段的值为DBNull,那么什么是DBNull。它与我们常常见到的Null又有什么差别?

Null指的是无效的对象引用。而DBNull是一个类。DBNull.Value是它唯一的实例。DBNull的实例DBNull.Value是数据库表中的空数据在.Net代码中的表现形式。我们知道,当数据库表中的可空字段没有被赋值时,数据库表中的该字段会被指定为Null,那么这个Null值在.Net代码中该怎样表示呢,使用的就是DBNull.Value。反过来说。在代码中。当一个字段的值等于DBNull.Value,那就说明这个字段在数据库中保存的值为Null。也就是说它在数据库中的值为空。所以,DBNull.Value对象指向有效的对象。并不像Null没有指向不论什么有效的对象。

再来看看我们实例中Students表的数据。例如以下图所看到的。

从图中能够看出。名为“周六”的学生的Age字段的值为空,确实存在异常信息所说的Age值为DBNull的情形。

那么,为什么,Age字段的值为DBNull就会抛出异常呢?我不就是想获取一下学生的Age值吗,没有值返回给我一个DBNull.Value不就得了吗。为什么会抛出异常呢?

继续深挖异常源头。通过查看异常的InnerException信息,得知该异常的内部异常为“指定的转换无效”,并定位到异常产生的问题代码。

[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
public int Age {get {try {return ((int)(this[this.tableStudents.AgeColumn]));}catch (global::System.InvalidCastException e) {throw new global::System.Data.StrongTypingException("表“Students”中列“Age”的值为DBNull。

", e); } } set { this[this.tableStudents.AgeColumn] = value; } }

问题代码为:

return ((int)(this[this.tableStudents.AgeColumn]));

查看问题代码中this[this.tableStudents.AgeColumn]的值。为DBNull.Value。再将这个DBNull.Value隐式转换成整型数据时产生了异常。由于两者之间根本无法进行类型转换。这段代码是在新建数据集及创建表时自己主动生成的。所以改动需谨慎。

可是不知道当时微软为什么不在这里加上一个特殊处理,要是返回值为DBNull.Value。就直接返回0。为什么不这样做。就不去瞎推測了。

找到解决方法要紧。

3 解决方法

我们除了使用“it.Age”的方式来获取字段的值外,还能够使用“it["Age"]”的方式来获取表中的字段值。且知道当数据库字段值为空时,“it["Age"]”获取到的值会是DBNull.Value且不会抛出异常。所以我们就能够使用“it["Age"]”方式得到Age的值再与DBNull.Value比較。当不相等时再进行类型转换操作。这样一切就OK啦。改动后的代码例如以下所看到的。

var newStudentList1 = sdt.Where(it => it["Age"] != DBNull.Value && (int)it["Age"] > 24).ToList();

再次运行程序,得到以下想要的结果。

转载于:https://www.cnblogs.com/yangykaifa/p/6772417.html

因DataTable的字段值为DBNull引发的异常相关推荐

  1. 类型初始值设定项引发异常. matlab,c# - “ MathWorks.MATLAB.NET.Utility.MWMCR”的类型初始值设定项引发了异常 - 堆栈内存溢出...

    " MathWorks.MATLAB.NET.Utility.MWMCR"的类型初始值设定项引发了异常: 我从c#调用,这是MatLab库编译器编译的DLL中的函数. using ...

  2. 类型初始值设定项引发异常

    -上午打开VS编译程序的时候,突然出现了这个运行时错误"类型初始值设定项引发异常".昨天还没有这个错误呢,今天就突然出现,搞得我一头雾水.上网搜了一下,发现有很多人遇到了这个问题. ...

  3. getdatatable mysql_C# 自定义MySqlHelp类,包含了获取DataTable的方法,但是调用时总是提示“类型初始值设定项引发异常”...

    代码:classMySqlHelper{privatestaticstringconStr=ConfigurationManager.ConnectionStrings["conListOf ...

  4. C#三种判断数据库中取出的字段值是否为空(NULL) 的方法

    操作数据库,需要判断返回的字段值是否为空,大致有以下三种方法: 1 通过System.DBNull判断,网上大部分都使用这个方法. DataTable dt;         //假设字段为name, ...

  5. linq 清除一条数据中的某个字段值_B端通用批量数据导入方案设计

    点击上方蓝色字体,关注我 B端通用批量数据导入方案设计 文 | 3548字 估计阅读 | 9分钟 引题 B端产品经常遇到大量数据录入的需求.如春季招聘完成后,给新招的120个员工建立员工档案,并创建员 ...

  6. “Lephone.Data.DbEntry”的类型初始值设定项引发异常。(DbEntry.net3.9)

    http://dbentry.codeplex.com/Thread/View.aspx?ThreadId=228796 呈现该控件时出错. "Lephone.Data.DbEntry&qu ...

  7. Mysql函数group_concat、find_in_set 多值分隔字符字段进行数据库字段值翻译

    Mysql函数group_concat.find_in_set进行数据库字段值翻译 场景 配方表:记录包含的原料 sources表示原料,字段值之间用逗号分隔 原料表:对应原料id和原料名称 现需要查 ...

  8. winform chart 添加数据报错_C# win Form开发 构造指定格式数据表字段值

    在进行Win Form开发时,需要实现对数据进行存储与管理,主要采用数据库管理系统SQL Server进行数据的存储.在项目教学过程中给出下面问题描述: 问题:数据表Competitor(参赛者)要求 ...

  9. java 反射获取父类的字段_java反射获取父类和子类字段值、赋值

    这里将告诉您java反射获取父类和子类字段值.赋值,具体操作过程:java反射获取字段值.赋值 import org.springframework.util.ReflectionUtils; imp ...

  10. SAP MM MM17里不能修改物料主数据'Purchasing Value Key'字段值?

    SAP MM MM17里不能修改物料主数据'Purchasing Value Key'字段值? 记得在D项目上线之前数据导入系统之后,业务提出一些物料采购视图里的'Purchasing value k ...

最新文章

  1. 配置Trunk实现相同Vlan通信
  2. java学习:Iterator数据加工厂
  3. Linux yum 命令
  4. 聚类算法K-Means, K-Medoids, GMM, Spectral clustering,Ncut
  5. 转载:Pixhawk源码笔记一:APM代码基本结构
  6. 雪城大学信息安全讲义 4.1~4.2
  7. mysql update语句卡死_oracle执行update语句时卡住问题分析及解决办法
  8. 运算符重载 返回类型说明符后加_Python3基础:从独特的角度看运算符重载
  9. 20 个实例玩转 Java 8 Stream,写的太好了!
  10. 问题排查证明方式:Unknown column NaN in field list
  11. HDOJ 2084 数塔 简单解题报告
  12. python比java_对比java和python对比
  13. allatori混淆工具_Java 代码混淆工具 Allatori
  14. html 怎么绘制曲线图,用html5绘制折线图的实例代码_html5教程技巧
  15. 第四周问题:Tu Hao's Problem
  16. 养乐多老师2017版韩语发音教程学习笔记
  17. 为什么穷人越穷,富人越富?
  18. Latex设置指定区域的行距
  19. Li feifei How we're teaching computers to understand pictures
  20. labview中前面板如何设置背景图片

热门文章

  1. [转]六步使用ICallbackEventHandler实现无刷新回调
  2. jsp文件创建后自动设置其pageEncoding的属性值为UTF-8
  3. MongoDB安装、配置与示例
  4. trigger 根据绑定到匹配元素的给定的事件类型执行所有的处理程序和行为。
  5. C# 匿名对象的写法
  6. jQuery-JS在iframe中获取父页面的值
  7. C#实现Base64编码与解码及编码名称和代码页(Encoding.GetEncoding)
  8. Python 参数解析(getopt模块)
  9. 15. Provide access to raw resources in resouce-managing classes
  10. linux版Nacos安装、集群配置