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

Fec*_*ore 4 c# nullable primary-key

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

if (BookID != null) {
Run Code Online (Sandbox Code Playgroud)

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

if (BookID > 0) {
Run Code Online (Sandbox Code Playgroud)

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

例:

BookID = GetBookID("my book title");
Run Code Online (Sandbox Code Playgroud)

Dan*_*ner 12

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

UPDATE

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

Book book = Book.GetById(id);
Run Code Online (Sandbox Code Playgroud)

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

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

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

Book book;
if (Book.TryGetById(out book))
{
    DoStuffWith(book);
}
else
{
    DoStuffWithoutBook();
}
Run Code Online (Sandbox Code Playgroud)

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

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

if (Book.Exists(id))
{
    Book book = Book.GetById(id).Order(100, supplier);
}
else
{
    DoStuffWithoutBook();
}
Run Code Online (Sandbox Code Playgroud)

  • +1一般来说,它不应该是可空的这一事实,至少在这种情况下是好的. (3认同)

Ree*_*sey 8

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

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