4

如果我在我的代码中使用 int 类型的 BookID,它对应于数据库表中的 int 主键字段(我正在使用 C# 和 SQL Server)......当我' m 在我的代码中传递 ID,使用可为空的 int 并检查 null 以查看 BookID 是否存在:

if (BookID != null) {

或者,分配一个与数据库中的实际值不对应的整数值(例如 0 或 -1)是一种更好的做法:

if (BookID > 0) {

编辑:为了进一步澄清,假设我只想返回书的 ID,而不是整个书对象。在数据库中,主键不可为空,如果我要对不存在的“我的书名”的 BookID 执行查询,那么我不会得到任何结果。这应该反映为空吗?

例子:

BookID = GetBookID("my book title");
4

5 回答 5

12

如果您有一个允许在数据库中使用 null 的值,则应使用Nullable<T>并避免引入Magic Numbers。但是如果BookId是一个(主)键,它可能不应该是可空的(除了它被用作外键)。

更新

对于查询数据库并没有找到匹配记录的问题,有几种解决方案。我更喜欢抛出异常,因为如果应用程序试图获取不存在的记录,这通常表示错误。

Book book = Book.GetById(id);

在这种情况下,如果返回值为 null,您会怎么做?可能这一行之后的代码想要对这本书做一些事情,在 null 的情况下,该方法通常什么也不做

  1. 抛出一个可以更好地完成的异常GetById()(除了调用者可能有更多关于异常的上下文信息)
  2. 立即返回 null 或需要调用者处理的错误代码,但这有效地重新发明了异常处理系统

如果绝对有效,不找匹配记录,我建议使用 TryGet 模式。

Book book;
if (Book.TryGetById(out book))
{
    DoStuffWith(book);
}
else
{
    DoStuffWithoutBook();
}

我相信这比返回 null 更好,因为 null 是一种神奇的值,我不喜欢在业务逻辑中看到实现细节(引用类型或可空值类型可以取名为 null 的特殊值) . 缺点是你失去了可组合性——你不能再写了Book.GetById(id).Order(100, supplier)

以下为您提供了可组合性,但有一个非常大的问题 - 这本书可能会在调用Exists()and之间被删除GetById(),因此我强烈建议不要使用这种模式。

if (Book.Exists(id))
{
    Book book = Book.GetById(id).Order(100, supplier);
}
else
{
    DoStuffWithoutBook();
}
于 2009-07-07T16:04:24.193 回答
8

我更喜欢使用可为空的 int - 这更直接地映射到数据库中的实际内容。

此外,很多时候没有适当的值可用于 null。使用 -1 表示 null 是不好的做法,IMO,因为 -1 通常是数据库中的有效值。

于 2009-07-07T16:01:54.323 回答
2

Db 中的主键通常不可为空,在大多数情况下,程序中的值也不应为空。但是在某些情况下,可能需要指示未找到的 Find() 函数,然后可以使用可为空的值。当你传递结果形式 Find。喜欢:

int? foundBookID = FindBook(title);
if (foundBookID.HasValue)
{
   int BookID = foundBookID.Value;  // not nullable
   ...
}
于 2009-07-07T16:21:31.177 回答
0

恕我直言,最好拥有(伪代码)

public struct Identifier {

   private int? presistanceID;

   public Identifier(int presistanceID){
     presistanceID = presistanceID;
   }

   public bool IsSetted {
     get {presistanceID.hasvalue};
   }
}

if (book.BookID.IsSetted){
}

book.BookID.ToString();

这是可读的,提供基本的类型检查,允许两个不变量(分配的 ID 和未分配的)并且对于 NullRerenceException 是安全的。

于 2009-07-07T16:24:39.113 回答
0

听起来像一个加载的问题。你问的方式,是的,肯定使用可为空的 int。我能想到的例外是,如果有很多现有代码已经使用/检查了 0 来表示未找到。在这种情况下,一致性可能是首选。可空类型相对较新,因此看到 0 检查并不罕见。

于 2009-07-07T16:47:04.230 回答