如何在数据访问层(C#)中表示空值

时间:2008-12-22 15:37:32

标签: c# .net nullable

只是想知道DAL是否有任何最佳实践来表示空值(来自可空列)。

我们目前拥有自己的内部DAL,并使用int.MinValue表示空值。然而,这种上升令开发人员认为在比较值时,我们故意在int.MinValue上强加另一个“添加”值,并且在DAL层中将int.MinValue用于空值这一事实令人困惑。所以其他人提出了来自.net 2.0的NullValue,但我们发现这种方法也存在性能和语法问题:

那么,你对此有何看法?其他着名的ORM如何处理空值?围绕这个问题是否有最好的做法?

6 个答案:

答案 0 :(得分:10)

为了表示可以为空的整数,我每次都使用Nullable<int>(又名int?)。这正是它的设计目标。您已经提供了几个链接,但是您是否可以完全说明您的可空类型语法问题,以及您已经看到重要性能问题的位置(请记住数据库调用可能 比进程中的任何转换更昂贵。

编辑:我注意到倒数第二个链接是涉及我的新闻组对话。在这种情况下我转向清除可空类型的原因是因为问题是围绕一个Web服务,它可能需要有效地将空值传递给没有可空值类型的平台。我不认为这适用于你所描述的情况。

答案 1 :(得分:1)

我使用像int这样的可空类型?等等。

答案 2 :(得分:1)

感谢您的快速回复。

我们仍在决定使用哪一个,我不知道在我们的最终会有多么可行,但我同意数据库访问将成为瓶颈。

我看到使用nullable的问题实际上是因为here中概述的内置.net运算符下的不同行为。

如果我使用可空类型,如果我想正确比较两个整数,我将不得不用Nullable.Compare语法乱丢我的代码库。我不确定这是否是最好的解决方案。

答案 3 :(得分:1)

作为答案添加,因为评论太长了。

如果你不得不用Nullable.Compare乱丢你的代码库,那你就错了。您不应该比较两个Nullable<int>值,除非您已经知道它们都是非空的。

唯一的例外是在完全不可避免的地方,例如:在聚合或排序时。如果您使用标准方法(例如Linq)来执行此操作,则无需实现任何特殊处理,因为Nullable<T>实现了IComparable<T>

有一个原因是,在SQL Server中,任何包含NULL项的表达式的计算结果为NULL。如果表达式中的某个术语为NULL,则表达式的结果为无意义 - 除非表达式明确指示(通过ISNULL或COALESCE)如果术语为NULL,该怎么做。这是一个应该在表达式中或表达式周围做出的决定,而不是全局决定。

例如,请考虑这个看似简单的逻辑:

if (qtyOrdered > qtyInStock)
{
   Reorder(qtyInStock - qtyOrdered);
}

如果qtyInStock为空,那将抛出异常。如果qtyInStock为空, 该逻辑应该做什么?我们不知道:这是一个必须在业务逻辑设计中解决的问题,而且还没有得到解决。

但有一件事我们几乎肯定知道:如果qtyInStock为空,则为Int.MinValue - qtyOrdered项生成新订单是错误的答案。如果您使用幻数来指示空值,这就是这样的逻辑。逻辑被打破,需要修复,而不是隐藏。

答案 4 :(得分:0)

在我的数据访问层中,它将null转换为对上下文有意义的值。我的DAL的目的是将数据与应用程序接口,因此DAL必须知道数据代表什么,然后设计者可以推断出一个好的新值。也许零是空整数字段的正确答案,也许错误信息可能会出现在文本字段中。

当我的应用程序读取数据时,它会获取数据,当它显示给最终用户时,他们会发现某些内容为零,文本应该显示为“无文本可用”这样的东西。

使用int?只是将空问题推高一级,现在就是我如何使用我的DAL。

答案 5 :(得分:0)

C.J。 Date认为在RDBMS上下文中不应存在null,部分原因是这些问题。你怎么避免他们?通过重新设计它们:以各种方式分割您的数据,以便无效的列变得无关紧要,并在这种情况下从逻辑设计中删除。换句话说,重新设计您的表格和列,以便每列都被约束为NOT NULL,但也有一个有意义的值(没有替换自定义标记,如int.MinValue)。

这是很多工作,人们会高兴地争论它是否值得,但如果你关心你的实现的性能和纯度那么多,那么也许这就是你想要的。

相关问题