猿问

使用重复的主键检测插入

我的 api 允许尝试添加具有相同主键的实体。但是,我想过滤由于这个原因而发生的 DbUpdateException,因为它们只会污染我的日志文件。我在生产中使用 Sqlite 进行测试和 Postgres,所以我想要一种可以返回一些异常类型以获取原因的方法。


慕哥9229398
浏览 333回答 3
3回答

慕雪6442864

对于 Sql Server,您可以使用SqlException.Numberof 的内部异常的属性DbUpdateException来识别Violation of PRIMARY KEY错误。对于主键冲突 SqlException.Number = 2627。你可以尝试这样的事情:try{    db.SaveChanges();}catch (DbUpdateException ex){    if (ex.InnerException is SqlException sqlEx && sqlEx.Number == 2627)    {    }}我相信 forSqlite和Postgres想法应该是一样的

胡子哥哥

我最终得到了一些 DbUpdateException 的扩展类,但仍然有点hacky:public static class UpdateExceptionHelper{    public enum UpdateExceptionKind    {        UniqueViolation,        ForeignKeyViolation,        Unknown    }    public static UpdateExceptionKind Kind(this DbUpdateException dbUpdateException)    {        var inner = dbUpdateException.InnerException;        switch (inner)        {            case null:                return UpdateExceptionKind.Unknown;            case SqliteException sqlite:                return sqlite.Kind();            case PostgresException postgres:                return postgres.Kind();            default:                throw new Exception($"Unsupported Database Provider with Exception Type: {inner.GetType().Name}");        }    }    private static UpdateExceptionKind Kind(this PostgresException e)    {        const string UNIQUE_VIOLATION = "23505";        const  string FOREIGN_KEY_VIOLATION = "23503";        switch (e.SqlState)        {            case UNIQUE_VIOLATION:                return UpdateExceptionKind.UniqueViolation;            case FOREIGN_KEY_VIOLATION:                return UpdateExceptionKind.ForeignKeyViolation;            default:                return UpdateExceptionKind.Unknown;        }    }    private static UpdateExceptionKind Kind(this SqliteException e)    {        const int SQLITE_CONSTRAINT_UNIQUE = 2067;        const int SQLITE_CONSTRAINT_PRIMARYKEY = 1555;        const int SQLITE_CONSTRAINT_FOREIGNKEY = 787;        switch (e.SqliteExtendedErrorCode)        {            case SQLITE_CONSTRAINT_PRIMARYKEY:            case SQLITE_CONSTRAINT_UNIQUE:                return UpdateExceptionKind.UniqueViolation;            case SQLITE_CONSTRAINT_FOREIGNKEY:                return UpdateExceptionKind.ForeignKeyViolation;            default:                return UpdateExceptionKind.Unknown;        }    }}
随时随地看视频慕课网APP
我要回答