当请求的PostgreSQL表找不到时,如何捕获异常并使用错误码

本文关键字:捕获异常 误码 错误 请求 PostgreSQL 找不到 | 更新日期: 2023-09-27 18:06:20

我正在使用实体框架,所以我相信我应该抓住NpgsqlException,因为它是PostgreSQL的。net数据提供者。假设我对context做一个查询。如果表在PostgreSQL数据库中不存在,我想捕获抛出的异常,然后手动创建它。下面的代码是如何插入实体的示例,如果需要的话,我尝试使用错误处理来创建表:

try
{
    return _context.Set(entityType).Add(entity);
}
catch (NpgsqlException)
{
    CreateEntityTable(entity); //a private method I made
    return _context.Set(entityType).Add(entity);
}

问题是:

  • 我不是100%确定我应该捕捉一个NpgsqlException

  • 我想确定,如果抛出异常,这是因为表不存在。我查阅了PostgreSQL文档中的错误代码,错误代码42P01是未定义的表。我想用它,但怎么用呢?我查找了NpgsqlException类的成员,我找到了ErrorCode。然而,这是一个int类型。如果我能把上面的代码改成如下的

    ,那就太好了
    try
    {
        return _context.Set(entityType).Add(entity);
    }
    catch (NpgsqlException ex)
    {
        if (ex.ErrorCode.Equals(42P01))
        {
            CreateEntityTable(entity); //a private method I made
            return _context.Set(entityType).Add(entity);
        }
    }
    

但是我不确定这是否有意义(我甚至不确定42P01怎么可能是int)。

当请求的PostgreSQL表找不到时,如何捕获异常并使用错误码

你将需要使用NpgsqlException的Code属性,因为它将包含PostgreSql错误代码。

更新你的例子:

try
{
    return _context.Set(entityType).Add(entity);
}
catch (NpgsqlException ex)
{
    if (ex.Code == "42P01")
    {
        CreateEntityTable(entity); //a private method I made
        return _context.Set(entityType).Add(entity);
    }
}

作为题外话,我建议不要在常规代码中执行模式更新。只有在安装程序中,或者在启动时作为升级,才能做这种性质的事情。

在asp.net Core 3.1和asp.net Core 5.0下测试和工作

try
{
    _context.Add(entity);
    await _context.SaveChangesAsync().ConfigureAwait(false);
    return RedirectToAction(nameof(Index));
}
catch (DbUpdateException ex)
{
    if (ex.GetBaseException() is PostgresException pgException)
    {
        switch (pgException.SqlState)
        {
            case "23505":
                ModelState.AddModelError(string.Empty, "This entity exists in the database");
                return View(yourViewModelFromRequest);
            default:
                throw;
         }
     }
}
Try
...
catch (NpgsqlException e)    
{
    switch (e.SqlState)
    {
         case "23505":
             MessageBox.Show("Some message...");
             break;
         default:
             MessageBox.Show("Some message. Details: " + e.Message);
             break;
    }
}