重复键异常实体框架

时间:2018-07-10 19:37:54

标签: c# .net entity-framework exception try-catch

所以我在捕获向数据库添加新记录的异常时遇到问题。

我正在使用实体框架

enter image description here

这是我的代码:

public void AddNewStandardEngineeredModel(StandardEngineeredModel model)
    {
        using (context = new LabelPrintingContext())
        {

            try
            {
                context.EngineeredModels.Add(model);
                context.SaveChanges();
            }
            catch (SqlException ex)
            {
                if (ex.Number == 2601)
                {
                    //Violation of primary key. Handle Exception
                }
                else throw;
            }
        }
    }

我也尝试了以下方法:

 public void AddNewStandardEngineeredModel(StandardEngineeredModel model)
    {
        using (context = new LabelPrintingContext())
        {

            try
            {
                context.EngineeredModels.Add(model);
                context.SaveChanges();
            }
            catch (UpdateException ex)
            {
                var sqlException = ex.InnerException as SqlException;

                if (sqlException != null && sqlException.Errors.OfType<SqlError>()
                    .Any(se => se.Number == 2601))
                {

                    // it's a dupe... do something about it
                }
                else
                {
                    // it's something else...
                    throw;
                }
            }
        }
    }

如果我只执行catch(Exception Ex),它将捕获该异常,但是我想检查该数字以更好地响应我的用户。这样,如果要添加重复项,我可以让他们知道并适当解决。

这里是错误的图片:

enter image description here

不太确定还要尝试什么方法来捕获特定的异常。任何建议都会有所帮助。

1 个答案:

答案 0 :(得分:1)

使用ORM时,经常会包装SqlException,有时会嵌套很多。因此,您需要一个帮助器函数来遍历异常树并找到SqlException(如果存在):

    static SqlException GetSqlException(Exception exception)
    {
        if (exception is SqlException sqlException) return sqlException;
        return exception.InnerException == null ? null : GetSqlException(exception.InnerException);
    }

然后,您可以使用喜欢的任何策略来捕获细粒度的异常,并处理SqlException(如果找到)。例如根据您的代码:

public void AddNewStandardEngineeredModel(StandardEngineeredModel model)
{
    using (context = new LabelPrintingContext())
    {

        try
        {
            context.EngineeredModels.Add(model);
            context.SaveChanges();
        }
        catch (Exception ex)
        {
            var sqlException = GetSqlException(ex);

            if (sqlException != null && sqlException.Errors.OfType<SqlError>()
                .Any(se => se.Number == 2601))
            {

                // it's a dupe... do something about it
            }
            else
            {
                // it's something else...
                throw;
            }
        }
    }
}