c# - 如果在数据库中找不到记录,则返回 (RecordNotFound) 异常或 null?

标签 c# exception

我不太确定在处理数据库中找不到的记录时首选的方法是什么。编写返回 null 的 Find 方法还是编写返回 RecordNotFoundException 的 Get 方法更好?

[AuthenticateFilter(UsernameAndSecretKey)]
[Route("api/v1/activities/emails/{id}")]
[HttpGet]
public IHttpActionResult GetEmailActivity(int id)
{
  try
  {
    // business logic service, could use only db service but this way we can do unit tests (just fill bl service method with fake objects)
    var service = new EmailActivityBlService();

    // 1. use Find method which returns null in case record with provided id does not exist in db
    var model = service.FindActivity(id);
    if( model != null )
      return Ok(model);
    return NotFound();  

   // 2. or is this approach better
   // throws RecordNotFoundException in case row by id is not found in database
   return Ok(service.GetActivity(id));
  }
  catch(RecordNotFoundException e) { return NotFound(); }
  catch(Exception e) { return InternalServerError(e); }
}

EmailActivityBlService 有下一个代码以防有人感兴趣(只显示重要部分):

private EmailActivityDbService _dbService;

public EmailActivityModel GetActivity(int id)
{
  var model = this._dbService.GetActivity(id);
  if( model == null )
    throw new RecordNotFoundException(); // I suppose System.Data.ObjectNotFound is also suitable
  return model;
}

public EmailActivityModel FindActivity(int id)
{
  // typical entity framework query
  // using(var context = new ..) { return contect.EmailActivity.Where()..SingleOrDefault().ConvertToModel();
  return this._dbService.GetActivity(id);
}

更新

与我的同事讨论后,我们决定采用此解决方案。至于为什么 GetActivity 返回 null 而不是抛出异常,我更喜欢 rboe 的回答:

So return null if it is can happen in your domain, that records do not exist (in my experience this is most often the case). If you expect a record to exist and it is not there, then it is valid to throw an exception.

[AuthenticateFilter(UsernameAndSecretKey)]
[Route("api/v1/activities/emails/{id}")]
[HttpGet]
public IHttpActionResult GetEmailActivity(int id)
{
   var service = new EmailActivityBlService();
   var model = service.GetActivity(id); // returns null in case activity is not found
   if( model != null )
     return Ok(model);
   return NotFound();
}

我们避免了方法中的任何 try-catch 并在异常发生时放置全局过滤器:

文件:App_Start\WebApiConfig.cs

public class WebApiExceptionFilter : ExceptionFilterAttribute
{
  public override void OnException(HttpActionExecutedContext actionExecutedContext)
  {
    actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, actionExecutedContext.Exception.Message, actionExecutedContext.Exception);
  }
}

最佳答案

两种方式都是有效的。

用异常还是返回值null表示不存在的记录是不同的强调。

存在异常以指示错误状态(发生异常的事情)。 catch-handler 中的代码专注于如何处理错误而不是包含业务逻辑。

如果您返回 null,那么它将是您模型中的正常且“非异常”状态。

所以返回 null 如果它可能发生在您的域中,即记录不存在(根据我的经验,这种情况最常见)。如果您希望记录存在而它不存在,则抛出 exception 是有效的。

关于c# - 如果在数据库中找不到记录,则返回 (RecordNotFound) 异常或 null?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39184684/

相关文章:

c# - 如果在具有自动增量的表上调用多个插入,Linq to SQL Datacontext 不会提交

c# - Mono/Linux 字符编码问题?

c# - 结构默认构造函数的属性

c++ - 什么时候应该使用 std::nothrow?

MySQL 在事务中捕获异常

java - 如何使用 jUnit 测试已处理的异常?

java - Exceptions 有多昂贵

c# - 更新一个已经序列化的对象

java.lang.reflect.inaccessibleobjectexception 无法使 jdk.internal.loader.classloaders

c# - 以编程方式获取 nuget 包的路径