如何处理 Null 和 DBNull
本主题介绍处理与不同类型相关的 null 值时的预期行为,并讨论用于检查特定字段或成员是否为 null(即是否存在)的选项。
XML
以下准则适用于 XML:
XML 值将永远不会作为 null 值从文档返回。 它返回空字符串或“不存在”错误。 如果是空字符串,则转换特定类型(例如,生成规则时将字段指定为整数类型)时可能会发生错误。
业务规则编辑器不允许将字段设置为 null 或将字段的类型设置为 object。
通过对象模型,可以将类型设置为 Object。 在本例中,返回的值是 XPath 计算到的类型- 浮点数、 布尔值或 字符串,具体取决于 XPath 表达式。
.NET 类
以下情况适用于 .NET 类:
如果返回类型不是 对象 类型,则不允许与 null 进行比较。
您可以将 null 作为非值类型的参数的参数传递,但是可能会产生运行时错误,这取决于成员的实现情况。
可以将派生自 Object 的类型字段设置为 null。
数据连接
以下情况适用于数据连接:
如果表允许对列使用 null,并且列类型不是 text、 ntext 和 image,则可以将任何数据库表列与 null 进行比较。
注意
业务规则编辑器允许你在条件中使用类型为 text 和 ntext 的列。 但是,您执行该策略时将会收到错误消息,指出:“text、ntext、和 image 数据类型不能比较或排序,除非使用 IS NULL 或 LIKE 运算符”。
如果数据库表允许列具有 null 值,则可以将该表的任何列设置为 null。
如果比较或设置为 null 的值类型,业务规则编辑器会自动将绑定中的成员类型设置为 对象;如果重置或替换 参数,它将更改回原始类型。
对于字符串类型,如果将类型设置为 null,它将类型更改为 object ,但如果与 null 进行比较,则将其保留为字符串。
无法比较或设置业务规则编辑器中的 DBNull.Value ,因为它不会将列类型更改为 对象。
该引擎会将 DBNull 值转换为 null 以便进行比较,并将 null 值转换为 DBNull 值以便插入到数据库中。
测试将忽略 null 值(这是 SQL Server 的工作方式)。 例如,如果规则为“IF db.column > 5 THEN .”,则仅测试 db.column 中具有值的行, 将跳过具有 null 的行。
TypedDataTable 和 TypedDataRow
以下情况适用于 TypedDataTable 和 TypedDataRow:
业务规则编辑器将字段类型更改为 对象 ,其方式与 DataConnection相同。
如果是 null 值,则测试将失败;除非与 null 进行比较。 例如,如果断言的任何行具有 null 值,则规则“IF db.column > 5 THEN”中会出现错误。
请注意,由于条件是并行计算的,因此“IF db.column != NULL AND db.column > 5 THEN”之类的测试仍将失败,因为两个测试都可能会针对每一行进行评估。
检查是否存在
编写业务规则时,在比较字段的值之前检查该字段是否存在是很正常的。 但是,如果该字段为 null(即不存在),则比较该值将引起错误。 假定存在以下规则:
如果存在产品/数量和产品/数量 > 1
如果 Product/Quantity 不存在,规则中将引发错误。 规避此问题的方法之一是将父节点传递到 helper 方法,如果元素值存在,helper 方法将返回元素值;如果元素值不存在,则返回其他内容。 请参阅以下规则。
规则 1
IF EXISTS(Product/Quantity) THEN ASSERT(CREATEOBJECT(typeof(Helper), Product/Quantity)
规则 2
IF Helper.Value == X THEN...
另一个可能的解决方案是创建以下规则:
IF Product/Quantity Exist Then CheckQuantityAndDoSomething(Product/Quantity)
在上例中,CheckQuantityAndDoSomething 函数将会检查参数值,如果条件满足则执行该函数。
注意
或者,可以修改 XML 事实的 XPath Field 属性以捕获任何错误,但不建议这样做。