C# 中的表索引异常

问题描述 投票:0回答:1

我有一个名为

Announcement
的表,它在列
Title
Code
上有唯一索引。

我正在使用 Entity Framework 6.0.26 进行 CRUD 操作,但在将数据插入/更新到上述列时遇到问题。

catch (Exception ex)
{
    if (ex.InnerException!.Message.Contains("unique index"))
    {
        if (ex.InnerException.Message.Contains("IX_Announcement_Code"))
        {
            throw new Exception("this code is already used");
        }

        if (ex.InnerException.Message.Contains("IX_Announcement_Title"))
        {
            throw new Exception("this title is already used");
        }
    }

    throw new Exception();
}

我正在使用这段代码来找出引发异常的原因 - 无论是否因为索引,但我知道这样做是一个不好的做法。

是否有与表索引相关的异常?

我知道我可以创建自定义方法进行验证(例如

Task<bool> TitleAlreadyExists(string title)
),但这不是我想要的。

我正在寻找更好的解决方案来处理数据库表索引异常。

c# .net entity-framework
1个回答
0
投票

考虑您的具体请求“[我正在寻找]更好的解决方案来捕获此异常”

捕获最具体的异常类型合理:

catch (DbUpdateException ex)

执行合理的健全性检查(也许使用异常过滤器 - 但当然你可以嵌套它)

catch (DbUpdateException ex) when ( ex.InnerException is null )
{
    // throw an application-specific Exception type
    throw new ApplicationUpdateFailedException(ex.Entries);
}

继续检测您的特殊情况

catch (DbUpdateException ex) when ( ex.InnerException is null )
{
    // throw an application-specific Exception type
    throw new ApplicationUpdateFailedException(ex.Entries);
}
catch (DbUpdateException ex) when ( ex.InnerException is not null && 
                                    ex.InnerException.Message.Contains("IX_Announcement_Code"))
{
    // throw an application-specific Exception type
    throw new ApplicationUpdateFailedDuplicateCodeException(ex.Entries);
}
catch (DbUpdateException ex) when ( ex.InnerException is not null && 
                                    ex.InnerException.Message.Contains("IX_Announcement_Title") )
{
    // throw an application-specific Exception type
    throw new ApplicationUpdateFailedDuplicateTitleException(ex.Entries);
}

为了使其更具可读性,您可能需要引入一些扩展方法,例如

internal static class DbUpdateExceptionExtensions
{
    internal static bool IsConflictForIndex(this DbUpdateException ex, string indexName) => 
       ex.InnerEcxeption is not null && 
       ex.InnerException.Message.Contains(indexName);
}

然后

catch (DbUpdateException ex) when ( ex.InnerException is null )
{
    // throw an application-specific Exception type
    throw new ApplicationUpdateFailedException(ex.Entries);
}
catch (DbUpdateException ex) when ( ex.IsConflictForIndex("IX_Announcement_Code"))
{
    // throw an application-specific Exception type
    throw new ApplicationUpdateFailedDuplicateCodeException(ex.Entries);
}
catch (DbUpdateException ex) when ( ex.IsConflictForIndex("IX_Announcement_Title") )
{
    // throw an application-specific Exception type
    throw new ApplicationUpdateFailedDuplicateTitleException(ex.Entries);
}

所有这些都假设您拥有特定于应用程序的异常类型,它们也可能形成继承树,因此您可以稍后决定是要单独捕获每个异常还是作为一组错误捕获。


单独说明:

不是一个好主意这样做

catch(Exception ex) // too broad anyway , ... but
{
    if( yadda yadda )
    {
        // ...
        throw new Exception("Message");
    }
    throw new Exception(); // Stacktrace reset, no message, ... == "Something went wrong" == useless
}

您正在失去有价值的信息。如果您首先必须做类似的事情,您可能需要考虑做类似的事情:

catch(Exception ex) // too broad anyway , ... but
{
    if( yadda yadda )
    {
        // ...
        throw SomethingElseException(ex);
    }
    throw;
}
© www.soinside.com 2019 - 2024. All rights reserved.