1

在我的ASP.NET MVC 3应用程序中,我使用EF 4.2。在我的数据库中,我对列有一个唯一的约束。实体框架4.2:获取正确的数据库错误

我尝试以看看有什么我可以插入相同的数据,但我得到下面的错误:

An error occurred while updating the entries. See the inner exception for details.

内部异常里面,我可以看到的唯一约束完整的错误。但我怎么能唯一捕获这个异常告诉用户这一点:

You are entering the same value again.

这是我目前做的:

try 
{ 
    UpdateModel<ConditionType>(conditionType, null, null, new string[] { "ConditionTypeId" }); 
    _conditionTypeRepository.Save(); 

    return RedirectToAction("conditiontype"); 
} 
catch (Exception ex) 
{ 
    ModelState.AddModelError("", "There was an error while updating: " + ex.Message); 
} 

但是,这是一个通用的方法。我想要做的是提供一个特定的信息。

有什么想法?

编辑:

我厌倦了下面这一次却没有赶上它:

catch (SqlException ex) 
{ 
    if (ex.Number == 2627) 
    { 
     ModelState.AddModelError("", "You are entering the same value again."); 
    } 

    ModelState.AddModelError("", "There was an error while updating the value: " + ex.Message); 
} 

我挖成一点点,事实证明,它抛出的异常类型System.Data.Entity.Infrastructure.DbUpdateException其中不包含例外号码。

编辑:

在这里,我是如何解决这个问题,但我相信这不是解决它的最好办法。任何想法如何重构这段代码?

catch (Exception ex) { 

    if (ex.InnerException.InnerException.GetType() == typeof(SqlException)) { 

     if (((SqlException)ex.InnerException.InnerException).Number == 2627) 
      ModelState.AddModelError("", "You are entering the same value again."); 
     else 
      ModelState.AddModelError("", "There was an error while updating the value: " + ex.Message); 

    } else { 
     ModelState.AddModelError("", "There was an error while updating the value: " + ex.Message); 
    } 
} 
+1

在调试窗口中单击加号,您将看到发生的内部异常。 – 2011-12-27 13:38:03

+1

已经讨论过类似的东西。看看这可以帮助你http://stackoverflow.com/questions/3694359/entity-framework-how-to-properly-handle-exceptions-that-occur-due-to-sql-constr – Pavan 2011-12-27 13:40:37

+0

@LasseEdsvik好的,我会告诉最终用户这样做。你仔细阅读过这个问题吗? – tugberk 2011-12-27 13:41:45

回答

3

你可以做这样的事情寻找一个内部异常是SQLEXCEPTION,然后处理SQL异常不同。

catch(Exception ex) 
{ 
    Exception current = ex; 
    SqlException se = null; 
    do 
    { 
     se = current.InnerException as SqlException; 
     current = current.InnerException; 
    } 
    while (current != null && se == null); 

    if (se != null) 
    { 
     // Do your SqlException processing here 
    } 
    else 
    { 
     // Do other exception processing here 
    } 
} 
+0

看起来很酷。现在给它一个尝试。 – tugberk 2011-12-27 14:24:54

+0

这不会执行,因为代码不下降到InnerExceptions。 – Designpattern 2013-08-01 09:21:35

+0

@Designpattern - 良好的捕捉。我的意图是走它(因此ex.Inner!= null),只是忘了实际更新变量。 – pstrjds 2013-08-01 14:15:57

0

为了获得最里面的异常,你可以做这样的事情:

SqlException se = null; 
Exception next = ex; 

while (next.InnerException != null) 
{ 
    se = next.InnerException as SqlException; 
    next = next.InnerException; 
} 

if (se != null) 
{ 
    // Do your SqlException processing here 
} 
else 
{ 
    // Do other exception processing here 
} 
0

人们还可以使用GetBaseException()方法,因为这将让你根本原因除外,它是把SQLException。