在处理int对象ID时,我应该使用可空的int吗?

时间:2009-07-07 16:00:37

标签: c# primary-key nullable

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

if (BookID != null) {

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

if (BookID > 0) {

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

示例:

BookID = GetBookID("my book title");

5 个答案:

答案 0 :(得分:12)

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

<强>更新

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

Book book = Book.GetById(id);

在这种情况下,您将使用null返回值做什么?可能这行之后的代码想要对本书做一些事情,而在null的情况下,该方法通常可以做什么呢?

  1. 抛出一个可以在GetById()中做得更好的异常(除了调用者可能有更多关于异常的上下文信息)
  2. 使用null返回immidiatly或需要调用者处理的错误代码,但这有效地重新发明了一个异常处理系统
  3. 如果绝对有效,不找到匹配的记录,我建议使用TryGet模式。

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

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

    以下内容为您提供了可组合性,但存在一个非常大的问题 - 在调用Exists()GetById()之间可能会删除该书,因此我强烈建议您不要使用此模式。 / p>

    if (Book.Exists(id))
    {
        Book book = Book.GetById(id).Order(100, supplier);
    }
    else
    {
        DoStuffWithoutBook();
    }
    

答案 1 :(得分:8)

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

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

答案 2 :(得分:2)

Db中的主键通常不可为空,在大多数情况下,程序中的值也不应该为空。但是有些情况像Find()函数可能需要指示not-found,然后可以使用可空值。当你传递结果表格时。像:

int? foundBookID = FindBook(title);
if (foundBookID.HasValue)
{
   int BookID = foundBookID.Value;  // not nullable
   ...
}

答案 3 :(得分: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安全。

答案 4 :(得分:0)

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

相关问题