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

问题描述 投票:2回答:2

我正在使用Entity Framework,所以我认为我应该抓住NpgsqlException,因为它是PostgreSQL的.NET数据提供程序。假设我要查询上下文。如果该表在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

  • 我想确保如果引发异常,那是因为该表不存在。我查找了the PostgreSQL documentation of error codes,错误代码42P01是未定义的表。我相信我想使用它,但是怎么用呢?我抬头看the members of the NpgsqlException class,发现错误代码。但是,这是一个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)。

任何帮助将不胜感激。

c# entity-framework postgresql error-handling npgsql
2个回答
3
投票

您将要使用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);
    }
}

顺便说一句,我建议您不要在常规代码中执行架构更新。仅在安装程序中或在作为升级启动时执行此类操作。


0
投票

经过测试并与ASP NET Core 3.1一起使用

                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, "Ky entitet ekziston ne databaze");
                                return View(waterProtocol);
                            default:
                                throw;
                        }
                    }
                }
© www.soinside.com 2019 - 2024. All rights reserved.