【问题标题】:Duplicate Key Exception Entity Framework重复键异常实体框架
【发布时间】:2018-12-18 17:58:48
【问题描述】:

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

我正在使用实体框架

这是我的代码:

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) 它将捕获异常,但我想检查该数字以便更好地响应我的用户。这样,如果要添加副本,我可以让他们知道并适当地修复它。

这是错误的图片:

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

【问题讨论】:

  • 至少说一下你model的主键是什么,它是一个身份吗?看来您的逻辑有错误。插入(填充)ID.
  • 我想检查号码以便更好地响应我的用户。这样,如果要添加副本,我可以让他们知道并适当地修复它。 很简单。不要让您的用户指定主键。
  • 主键是一个字符串。型号是主键。我只想知道如何处理异常。
  • 好吧,我不希望数据库中有重复的型号,因此将我的型号设置为主键是最有意义的。
  • 我只是想知道为什么这些 catch() 语句没有捕获到异常,而不是关于我的主键是什么等,我知道主键是重复的,这是问题所在程序的工作原理是,如果抛出重复键异常,它将尝试添加模型,而不是尝试添加它我想问用户是否要更新记录。

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


【解决方案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;
            }
        }
    }
}

【讨论】:

  • 这是完美的谢谢。效果很好。异常被包装这么多有点烦人。在找到我想要的异常之前经历了 4 次。
猜你喜欢
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-21
  • 2019-01-30
  • 1970-01-01
相关资源
最近更新 更多