C#数据库访问:DBNull与null的区别

13

我们在这里使用自己的ORM,并为所有数据库表提供强类型包装器。我们还允许执行弱类型的临时SQL语句,但这些查询仍然通过同一类来从数据读取器中获取值。

在将该类调整为与Oracle配合使用时,我们遇到了一个有趣的问题。是更好地使用DBNull.Value还是null?使用DBNull.Value是否有任何好处?使用null似乎更“正确”,因为我们已经将自己与数据库世界分离开来,但是有一些影响(例如,在值为空时不能盲目地使用 ToString()),因此这绝对是我们需要做出明智决定的事情。

4个回答

15

我发现使用null比DB null更好。

原因是,正如你所说,这样可以将自己与数据库世界分离开来。

一般来说,检查引用类型以确保它们不为null是良好的编程实践。你将会为除DB数据以外的事物检查null值,我发现最好在整个系统中保持一致性,使用null而不是DBNull

从长远来看,在架构上,我认为这是更好的解决方案。


7
如果您已经编写了自己的ORM,那么我会建议使用null,因为您可以根据需要使用它。我认为DBNull最初仅用于避免值类型(int、DateTime等)不能为null的事实,因此不返回某些值,如零或DateTime.Min,这将意味着null(不好,不好),他们创建了DBNull来表示这一点。也许还有更多原因,但我总是认为这是原因。然而,现在我们在C# 3.0中有可空类型,DBNull就不再必要了。事实上,LINQ to SQL只是在各个地方使用null。没有任何问题。拥抱未来…使用null。;-)

我认为DBNull仍然有一些用途。至少在sqlite中,我可以测试ExecuteScalar()返回的值是否明确存储在数据库中。考虑表foo(a int,b int);只有一行(1,null)。如果我们在“SELECT b FROM foo WHERE A = 1”的命令上执行ExecuteScalar,它将返回DBNull.Value(该行存在null被存储)。如果我在“SELECT b FROM foo WHERE A = 2”上调用ExecuteScalar,则会返回null(不存在这样的行)。也许您可以通过DataReader实现相同的结果,但我确实欣赏它的方便性。 - fostandy
有趣。在使用ORM进行数据库访问时,我很少在代码中显式地使用ExecuteScalar。通常我会检索完整的实体对象并以这种方式查看它们的值。因此,如果实体本身为空,则是一件事,如果值为空,则是另一件事。只是不同的做法。我承认,如果您只需要一个单一的值,ExecuteScalar更有效率。 - jeremcc

3

根据我的经验,.NET DataTables 和 TableAdapters 与 DBNull 的配合更好。当强类型时,它还会开启一些特殊方法,例如 DataRow.IsFirstNameNull。

我希望我能给你一个更好的技术答案,但对我来说,最重要的是在处理与数据库相关的对象时使用 DBNull,而在处理对象和 .NET 相关代码时使用“标准” null。


1

使用 DBNull
在使用 null 时,我们遇到了一些问题。
如果我没记错的话,你不能将 null 值插入到字段中,只能使用 DBNull。
可能仅与 Oracle 相关,抱歉,我不再知道详细信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接